From: Heeyong Song Date: Fri, 1 Sep 2017 00:42:59 +0000 (+0900) Subject: Revert "[Tizen] Revert "Support screen rotation"" X-Git-Tag: accepted/tizen/4.0/unified/20170907.192420~9 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git;a=commitdiff_plain;h=88d565576965f2b4a0a5c1cb870606194cd7b241 Revert "[Tizen] Revert "Support screen rotation"" This reverts commit d370ec687e37a2adb6cc230625bb289361f11446. Change-Id: Ie7e97a01f15117dfef6bc40ed813cb1a7ec972ca --- diff --git a/adaptors/base/combined-update-render/combined-update-render-controller.cpp b/adaptors/base/combined-update-render/combined-update-render-controller.cpp index 715053f..2b3ed58 100644 --- a/adaptors/base/combined-update-render/combined-update-render-controller.cpp +++ b/adaptors/base/combined-update-render/combined-update-render-controller.cpp @@ -107,7 +107,8 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS mPendingRequestUpdate( FALSE ), mUseElapsedTimeAfterWait( FALSE ), mNewSurface( NULL ), - mPostRendering( FALSE ) + mPostRendering( FALSE ), + mSurfaceResized( FALSE ) { LOG_EVENT_TRACE; @@ -284,6 +285,26 @@ void CombinedUpdateRenderController::ReplaceSurface( RenderSurface* newSurface ) LOG_EVENT( "Surface replaced, event-thread continuing" ); } +void CombinedUpdateRenderController::ResizeSurface() +{ + LOG_EVENT_TRACE; + + LOG_EVENT( "Starting to resize the surface, event-thread blocked" ); + + // Start resizing the surface. + { + ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); + mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will resize the surface now + mSurfaceResized = TRUE; + mUpdateRenderThreadWaitCondition.Notify( lock ); + } + + // Wait until the surface has been resized + sem_wait( &mEventThreadSemaphore ); + + LOG_EVENT( "Surface resized, event-thread continuing" ); +} + void CombinedUpdateRenderController::SetRenderRefreshRate( unsigned int numberOfFramesPerRender ) { // Not protected by lock, but written to rarely so not worth adding a lock when reading @@ -413,6 +434,19 @@ void CombinedUpdateRenderController::UpdateRenderThread() } ////////////////////////////// + // RESIZE SURFACE + ////////////////////////////// + + // The resizing will be applied in the next loop + bool surfaceResized = ShouldSurfaceBeResized(); + if( DALI_UNLIKELY( surfaceResized ) ) + { + LOG_UPDATE_RENDER_TRACE_FMT( "Resizing Surface" ); + mRenderHelper.ResizeSurface(); + SurfaceResized(); + } + + ////////////////////////////// // UPDATE ////////////////////////////// @@ -537,12 +571,14 @@ bool CombinedUpdateRenderController::UpdateRenderReady( bool& useElapsedTime, bo while( ( ! mUpdateRenderRunCount || // Should try to wait if event-thread has paused the Update/Render thread ( mUpdateRenderThreadCanSleep && ! updateRequired && ! mPendingRequestUpdate ) ) && // Ensure we wait if we're supposed to be sleeping AND do not require another update ! mDestroyUpdateRenderThread && // Ensure we don't wait if the update-render-thread is supposed to be destroyed - ! mNewSurface ) // Ensure we don't wait if we need to replace the surface + ! mNewSurface && // Ensure we don't wait if we need to replace the surface + ! mSurfaceResized ) // Ensure we don't wait if we need to resize the surface { LOG_UPDATE_RENDER( "WAIT: mUpdateRenderRunCount: %d", mUpdateRenderRunCount ); LOG_UPDATE_RENDER( " mUpdateRenderThreadCanSleep: %d, updateRequired: %d, mPendingRequestUpdate: %d", mUpdateRenderThreadCanSleep, updateRequired, mPendingRequestUpdate ); LOG_UPDATE_RENDER( " mDestroyUpdateRenderThread: %d", mDestroyUpdateRenderThread ); LOG_UPDATE_RENDER( " mNewSurface: %d", mNewSurface ); + LOG_UPDATE_RENDER( " mSurfaceResized: %d", mSurfaceResized ); // Reset the time when the thread is waiting, so the sleep-until time for // the first frame after resuming should be based on the actual start time @@ -561,6 +597,7 @@ bool CombinedUpdateRenderController::UpdateRenderReady( bool& useElapsedTime, bo LOG_COUNTER_UPDATE_RENDER( "mUpdateRenderThreadCanSleep: %d, updateRequired: %d, mPendingRequestUpdate: %d", mUpdateRenderThreadCanSleep, updateRequired, mPendingRequestUpdate ); LOG_COUNTER_UPDATE_RENDER( "mDestroyUpdateRenderThread: %d", mDestroyUpdateRenderThread ); LOG_COUNTER_UPDATE_RENDER( "mNewSurface: %d", mNewSurface ); + LOG_COUNTER_UPDATE_RENDER( "mSurfaceResized: %d", mSurfaceResized ); mUseElapsedTimeAfterWait = FALSE; mUpdateRenderThreadCanSleep = FALSE; @@ -593,6 +630,22 @@ void CombinedUpdateRenderController::SurfaceReplaced() sem_post( &mEventThreadSemaphore ); } +bool CombinedUpdateRenderController::ShouldSurfaceBeResized() +{ + ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); + + bool surfaceSized = mSurfaceResized; + mSurfaceResized = FALSE; + + return surfaceSized; +} + +void CombinedUpdateRenderController::SurfaceResized() +{ + // Just increment the semaphore + sem_post( &mEventThreadSemaphore ); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // ALL THREADS /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -637,6 +690,7 @@ void CombinedUpdateRenderController::PostRenderWaitForCompletion() ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); while( mPostRendering && ! mNewSurface && // We should NOT wait if we're replacing the surface + ! mSurfaceResized && // We should NOT wait if we're resizing the surface ! mDestroyUpdateRenderThread ) { mUpdateRenderThreadWaitCondition.Wait( lock ); diff --git a/adaptors/base/combined-update-render/combined-update-render-controller.h b/adaptors/base/combined-update-render/combined-update-render-controller.h index 6f409cf..318b085 100644 --- a/adaptors/base/combined-update-render/combined-update-render-controller.h +++ b/adaptors/base/combined-update-render/combined-update-render-controller.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_COMBINED_UPDATE_RENDER_CONTROLLER_H__ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -126,6 +126,11 @@ public: virtual void ReplaceSurface( RenderSurface* surface ); /** + * @copydoc ThreadControllerInterface::ResizeSurface() + */ + virtual void ResizeSurface(); + + /** * @copydoc ThreadControllerInterface::SetRenderRefreshRate() */ virtual void SetRenderRefreshRate( unsigned int numberOfFramesPerRender ); @@ -216,6 +221,21 @@ private: void SurfaceReplaced(); /** + * Checks to see if the surface needs to be resized. + * This will lock the mutex in mUpdateRenderThreadWaitCondition. + * + * @return true if the surface should be resized, false otherwise + */ + bool ShouldSurfaceBeResized(); + + /** + * Called by the Update/Render thread after a surface has been resized. + * + * This will lock the mutex in mEventThreadWaitCondition + */ + void SurfaceResized(); + + /** * Helper for the thread calling the entry function * @param[in] This A pointer to the current object */ @@ -312,6 +332,7 @@ private: RenderSurface* volatile mNewSurface; ///< Will be set to the new-surface if requested (set by the event-thread, read & cleared by the update-render thread). volatile unsigned int mPostRendering; ///< Whether post-rendering is taking place (set by the event & render threads, read by the render-thread). + volatile unsigned int mSurfaceResized; ///< Will be set to resize the surface (set by the event-thread, read & cleared by the update-render thread). }; } // namespace Adaptor diff --git a/adaptors/base/render-helper.cpp b/adaptors/base/render-helper.cpp index 1d97128..c77d2c9 100644 --- a/adaptors/base/render-helper.cpp +++ b/adaptors/base/render-helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -38,7 +38,8 @@ RenderHelper::RenderHelper( AdaptorInternalServices& adaptorInterfaces ) : mGLES( adaptorInterfaces.GetGlesInterface() ), mEglFactory( &adaptorInterfaces.GetEGLFactoryInterface()), mEGL( NULL ), - mSurfaceReplaced( false ) + mSurfaceReplaced( false ), + mSurfaceResized( false ) { // set the initial values before render thread starts mSurface = adaptorInterfaces.GetRenderSurfaceInterface(); @@ -125,6 +126,11 @@ void RenderHelper::ReplaceSurface( RenderSurface* newSurface ) mSurfaceReplaced = true; } +void RenderHelper::ResizeSurface() +{ + mSurfaceResized = true; +} + void RenderHelper::ShutdownEgl() { if( mSurface ) @@ -143,7 +149,7 @@ bool RenderHelper::PreRender() { if( mSurface ) { - mSurface->PreRender( *mEGL, mGLES ); + mSurface->PreRender( *mEGL, mGLES, mSurfaceResized ); } mGLES.PreRender(); return true; @@ -157,9 +163,10 @@ void RenderHelper::PostRender() if( mSurface ) { // Inform the surface that rendering this frame has finished. - mSurface->PostRender( *mEGL, mGLES, mDisplayConnection, mSurfaceReplaced ); + mSurface->PostRender( *mEGL, mGLES, mDisplayConnection, mSurfaceReplaced, mSurfaceResized ); } mSurfaceReplaced = false; + mSurfaceResized = false; } } // namespace Adaptor diff --git a/adaptors/base/render-helper.h b/adaptors/base/render-helper.h index 62266fa..5d26d16 100644 --- a/adaptors/base/render-helper.h +++ b/adaptors/base/render-helper.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_RENDER_HELPER_H__ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -102,6 +102,13 @@ public: void ReplaceSurface( RenderSurface* newSurface ); /** + * Resize the rendering surface. + * + * @note Called from render thread + */ + void ResizeSurface(); + + /** * Shuts down EGL. * * @note Called from render thread @@ -140,6 +147,7 @@ private: // Data RenderSurface* mSurface; ///< Current surface Dali::DisplayConnection* mDisplayConnection; ///< Display connection bool mSurfaceReplaced; ///< True when new surface has been initialized. + bool mSurfaceResized; ///< True when the surface is resized. }; } // namespace Adaptor diff --git a/adaptors/base/thread-controller-interface.h b/adaptors/base/thread-controller-interface.h index 4542fe5..2c8e8eb 100644 --- a/adaptors/base/thread-controller-interface.h +++ b/adaptors/base/thread-controller-interface.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_THREAD_CONTROLLER_INTERFACE_H__ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -84,6 +84,11 @@ public: virtual void ReplaceSurface( RenderSurface* surface ) = 0; /** + * Resize the surface. + */ + virtual void ResizeSurface() = 0; + + /** * @copydoc Dali::Adaptor::SetRenderRefreshRate() */ virtual void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender ) = 0; diff --git a/adaptors/base/thread-controller.cpp b/adaptors/base/thread-controller.cpp index 84d4cf8..f84bb93 100644 --- a/adaptors/base/thread-controller.cpp +++ b/adaptors/base/thread-controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -90,6 +90,11 @@ void ThreadController::ReplaceSurface( RenderSurface* newSurface ) mThreadControllerInterface->ReplaceSurface( newSurface ); } +void ThreadController::ResizeSurface() +{ + mThreadControllerInterface->ResizeSurface(); +} + void ThreadController::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender ) { mThreadControllerInterface->SetRenderRefreshRate( numberOfVSyncsPerRender ); diff --git a/adaptors/base/thread-controller.h b/adaptors/base/thread-controller.h index d9b8976..6feddc1 100644 --- a/adaptors/base/thread-controller.h +++ b/adaptors/base/thread-controller.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_THREAD_CONTROLLER_H__ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -104,6 +104,11 @@ public: void ReplaceSurface( RenderSurface* surface ); /** + * Resize the surface. + */ + void ResizeSurface(); + + /** * @copydoc Dali::Adaptor::SetRenderRefreshRate() */ void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender ); diff --git a/adaptors/common/adaptor-impl.cpp b/adaptors/common/adaptor-impl.cpp index 748012e..600a2a3 100644 --- a/adaptors/common/adaptor-impl.cpp +++ b/adaptors/common/adaptor-impl.cpp @@ -393,10 +393,17 @@ void Adaptor::FeedKeyEvent( KeyEvent& keyEvent ) void Adaptor::ReplaceSurface( Any nativeWindow, RenderSurface& surface ) { + PositionSize positionSize = surface.GetPositionSize(); + + // let the core know the surface size has changed + mCore->SurfaceResized( positionSize.width, positionSize.height ); + + mResizedSignal.Emit( mAdaptor ); + mNativeWindow = nativeWindow; mSurface = &surface; - // flush the event queue to give update and render threads chance + // flush the event queue to give the update-render thread chance // to start processing messages for new camera setup etc as soon as possible ProcessCoreEvents(); @@ -695,7 +702,7 @@ void Adaptor::OnDamaged( const DamageArea& area ) RequestUpdate(); } -void Adaptor::SurfaceSizeChanged( Dali::Adaptor::SurfaceSize surfaceSize ) +void Adaptor::SurfaceResizePrepare( Dali::Adaptor::SurfaceSize surfaceSize ) { // let the core know the surface size has changed mCore->SurfaceResized( surfaceSize.GetWidth(), surfaceSize.GetHeight() ); @@ -703,6 +710,16 @@ void Adaptor::SurfaceSizeChanged( Dali::Adaptor::SurfaceSize surfaceSize ) mResizedSignal.Emit( mAdaptor ); } +void Adaptor::SurfaceResizeComplete( Dali::Adaptor::SurfaceSize surfaceSize ) +{ + // flush the event queue to give the update-render thread chance + // to start processing messages for new camera setup etc as soon as possible + ProcessCoreEvents(); + + // this method blocks until the render thread has completed the resizing. + mThreadController->ResizeSurface(); +} + void Adaptor::NotifySceneCreated() { GetCore().SceneCreated(); diff --git a/adaptors/common/adaptor-impl.h b/adaptors/common/adaptor-impl.h index 425bfcf..f48f29e 100644 --- a/adaptors/common/adaptor-impl.h +++ b/adaptors/common/adaptor-impl.h @@ -338,7 +338,12 @@ public: /** * Informs core the surface size has changed */ - void SurfaceSizeChanged( Dali::Adaptor::SurfaceSize surfaceSize ); + void SurfaceResizePrepare( Dali::Adaptor::SurfaceSize surfaceSize ); + + /** + * Informs ThreadController the surface size has changed + */ + void SurfaceResizeComplete( Dali::Adaptor::SurfaceSize surfaceSize ); public: //AdaptorInternalServices diff --git a/adaptors/common/adaptor.cpp b/adaptors/common/adaptor.cpp index a6810c7..847f42e 100644 --- a/adaptors/common/adaptor.cpp +++ b/adaptors/common/adaptor.cpp @@ -184,11 +184,6 @@ void Adaptor::SetStereoBase( float stereoBase ) mImpl->SetStereoBase( stereoBase ); } -void Adaptor::SurfaceSizeChanged( SurfaceSize surfaceSize ) -{ - mImpl->SurfaceSizeChanged( surfaceSize ); -} - Adaptor::Adaptor() : mImpl( NULL ) { diff --git a/adaptors/common/application-impl.cpp b/adaptors/common/application-impl.cpp index 29e9250..5e73d5e 100644 --- a/adaptors/common/application-impl.cpp +++ b/adaptors/common/application-impl.cpp @@ -404,7 +404,6 @@ void Application::ReplaceWindow( const PositionSize& positionSize, const std::st Dali::RenderSurface* renderSurface = windowImpl.GetSurface(); Any nativeWindow = newWindow.GetNativeHandle(); - Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SurfaceSizeChanged( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).ReplaceSurface(nativeWindow, *renderSurface); mWindow = newWindow; mWindowPositionSize = positionSize; diff --git a/adaptors/devel-api/adaptor-framework/render-surface.h b/adaptors/devel-api/adaptor-framework/render-surface.h index 61fd74d..9739770 100644 --- a/adaptors/devel-api/adaptor-framework/render-surface.h +++ b/adaptors/devel-api/adaptor-framework/render-surface.h @@ -2,7 +2,7 @@ #define __DALI_RENDER_SURFACE_H__ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -134,9 +134,10 @@ public: * a surface to render onto. * @param[in] egl The Egl interface * @param[in] glAbstraction OpenGLES abstraction interface + * @param[in] resizingSurface True if the surface is being resized * @return True if the operation is successful, False if the operation failed */ - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ) = 0; + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ) = 0; /** * @brief Invoked by render thread after Core::Render @@ -144,8 +145,9 @@ public: * @param[in] glAbstraction OpenGLES abstraction interface * @param[in] displayConnection display connection * @param[in] replacingSurface True if the surface is being replaced. + * @param[in] resizingSurface True if the surface is being resized. */ - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ) = 0; + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) = 0; /** * @brief Invoked by render thread when the thread should be stop diff --git a/adaptors/ecore/wayland/pixmap-render-surface-ecore-wl.cpp b/adaptors/ecore/wayland/pixmap-render-surface-ecore-wl.cpp index cc3d05b..4acb518 100644 --- a/adaptors/ecore/wayland/pixmap-render-surface-ecore-wl.cpp +++ b/adaptors/ecore/wayland/pixmap-render-surface-ecore-wl.cpp @@ -107,13 +107,13 @@ void PixmapRenderSurface::StartRender() // FIXME } -bool PixmapRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& ) +bool PixmapRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction&, bool ) { // nothing to do for pixmaps return true; } -void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ) +void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) { // flush gl instruction queue glAbstraction.Flush(); @@ -147,7 +147,7 @@ void PixmapRenderSurface::SetThreadSynchronization( ThreadSynchronizationInterfa void PixmapRenderSurface::CreateWlRenderable() { // check we're creating one with a valid size - DALI_ASSERT_ALWAYS( mPosition.width > 0 && mPosition.height > 0 && "Pixmap size is invalid" ); + DALI_ASSERT_ALWAYS( mPositionSize.width > 0 && mPositionSize.height > 0 && "Pixmap size is invalid" ); // FIXME } diff --git a/adaptors/ecore/wayland/render-surface-ecore-wl.cpp b/adaptors/ecore/wayland/render-surface-ecore-wl.cpp index 3596e34..2db6f23 100644 --- a/adaptors/ecore/wayland/render-surface-ecore-wl.cpp +++ b/adaptors/ecore/wayland/render-surface-ecore-wl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -41,11 +41,11 @@ EcoreWlRenderSurface::EcoreWlRenderSurface(Dali::PositionSize positionSize, Any surface, const std::string& name, bool isTransparent) -: mPosition(positionSize), - mTitle(name), - mRenderNotification(NULL), - mColorDepth(isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24), - mOwnSurface(false) +: mPositionSize( positionSize ), + mTitle( name ), + mRenderNotification( NULL ), + mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ), + mOwnSurface( false ) { } @@ -106,7 +106,7 @@ Ecore_Wl_Window* EcoreWlRenderSurface::GetDrawable() PositionSize EcoreWlRenderSurface::GetPositionSize() const { - return mPosition; + return mPositionSize; } void EcoreWlRenderSurface::MoveResize( Dali::PositionSize positionSize ) diff --git a/adaptors/ecore/wayland/window-impl-ecore-wl.cpp b/adaptors/ecore/wayland/window-impl-ecore-wl.cpp index 73c0c5a..6f9b2a7 100644 --- a/adaptors/ecore/wayland/window-impl-ecore-wl.cpp +++ b/adaptors/ecore/wayland/window-impl-ecore-wl.cpp @@ -68,11 +68,7 @@ struct Window::EventHandler */ EventHandler( Window* window ) : mWindow( window ), - mWindowPropertyHandler( NULL ), - mWindowIconifyStateHandler( NULL ), - mWindowVisibilityStateHandler( NULL ), - mWindowFocusInHandler( NULL ), - mWindowFocusOutHandler( NULL ), + mEcoreEventHandler(), mEcoreWindow( 0 ), mDisplay( NULL ), mEventQueue( NULL ), @@ -98,10 +94,12 @@ struct Window::EventHandler if( mWindow->mEcoreEventHander ) { - mWindowIconifyStateHandler = ecore_event_handler_add( ECORE_WL_EVENT_WINDOW_ICONIFY_STATE_CHANGE, EcoreEventWindowIconifyStateChanged, this ); - mWindowVisibilityStateHandler = ecore_event_handler_add( ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE, EcoreEventWindowVisibilityChanged, this ); - mWindowFocusInHandler = ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_IN, EcoreEventWindowFocusIn, this ); - mWindowFocusOutHandler = ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut, this ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_WINDOW_ICONIFY_STATE_CHANGE, EcoreEventWindowIconifyStateChanged, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE, EcoreEventWindowVisibilityChanged, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_IN, EcoreEventWindowFocusIn, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_OUTPUT_TRANSFORM, EcoreEventOutputTransform, this) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_IGNORE_OUTPUT_TRANSFORM, EcoreEventIgnoreOutputTransform, this) ); } mDisplay = ecore_wl_display_get(); @@ -130,30 +128,11 @@ struct Window::EventHandler */ ~EventHandler() { - if ( mWindowPropertyHandler ) + for( Dali::Vector< Ecore_Event_Handler* >::Iterator iter = mEcoreEventHandler.Begin(), endIter = mEcoreEventHandler.End(); iter != endIter; ++iter ) { - ecore_event_handler_del( mWindowPropertyHandler ); - } - - if ( mWindowIconifyStateHandler ) - { - ecore_event_handler_del( mWindowIconifyStateHandler ); - } - - if ( mWindowVisibilityStateHandler ) - { - ecore_event_handler_del( mWindowVisibilityStateHandler ); - } - - if( mWindowFocusInHandler ) - { - ecore_event_handler_del( mWindowFocusInHandler ); - } - - if( mWindowFocusOutHandler ) - { - ecore_event_handler_del( mWindowFocusOutHandler ); + ecore_event_handler_del( *iter ); } + mEcoreEventHandler.Clear(); if( mEventQueue ) { @@ -163,12 +142,6 @@ struct Window::EventHandler // Static methods - /// Called when the window properties are changed. - static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event ) - { - return EINA_FALSE; - } - /// Called when the window iconify state is changed. static Eina_Bool EcoreEventWindowIconifyStateChanged( void* data, int type, void* event ) { @@ -259,6 +232,36 @@ struct Window::EventHandler return ECORE_CALLBACK_PASS_ON; } + /// Called when the output is transformed + static Eina_Bool EcoreEventOutputTransform( void* data, int type, void* event ) + { + Ecore_Wl_Event_Output_Transform* transformEvent( static_cast< Ecore_Wl_Event_Output_Transform* >( event ) ); + EventHandler* handler( static_cast< EventHandler* >( data ) ); + + if ( handler && handler->mWindow && transformEvent->output == ecore_wl_window_output_find( handler->mEcoreWindow ) ) + { + ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( handler->mWindow->mSurface ) ); + wlSurface->OutputTransformed(); + } + + return ECORE_CALLBACK_PASS_ON; + } + + /// Called when the output transform should be ignored + static Eina_Bool EcoreEventIgnoreOutputTransform( void* data, int type, void* event ) + { + Ecore_Wl_Event_Ignore_Output_Transform* ignoreTransformEvent( static_cast< Ecore_Wl_Event_Ignore_Output_Transform* >( event ) ); + EventHandler* handler( static_cast< EventHandler* >( data ) ); + + if ( handler && handler->mWindow && ignoreTransformEvent->win == handler->mEcoreWindow ) + { + ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( handler->mWindow->mSurface ) ); + wlSurface->OutputTransformed(); + } + + return ECORE_CALLBACK_PASS_ON; + } + static void RegistryGlobalCallback( void* data, struct wl_registry *registry, uint32_t name, const char* interface, uint32_t version ) { Window::EventHandler* eventHandler = static_cast< Window::EventHandler* >( data ); @@ -357,11 +360,7 @@ struct Window::EventHandler // Data Window* mWindow; - Ecore_Event_Handler* mWindowPropertyHandler; - Ecore_Event_Handler* mWindowIconifyStateHandler; - Ecore_Event_Handler* mWindowVisibilityStateHandler; - Ecore_Event_Handler* mWindowFocusInHandler; - Ecore_Event_Handler* mWindowFocusOutHandler; + Dali::Vector< Ecore_Event_Handler* > mEcoreEventHandler; Ecore_Wl_Window* mEcoreWindow; wl_display* mDisplay; @@ -907,43 +906,15 @@ bool Window::IsVisible() const void Window::RotationDone( int orientation, int width, int height ) { - mAdaptor->SurfaceSizeChanged( Dali::Adaptor::SurfaceSize( width, height ) ); + ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) ); + wlSurface->RequestRotation( orientation, width, height ); + + mAdaptor->SurfaceResizePrepare( Dali::Adaptor::SurfaceSize( width, height ) ); // Emit signal mResizedSignal.Emit( Dali::DevelWindow::WindowSize( width, height ) ); - Dali::Window::WindowOrientation windowOrientation; - switch( orientation ) - { - case 0: - { - windowOrientation = Dali::Window::PORTRAIT; - break; - } - case 90: - { - windowOrientation = Dali::Window::LANDSCAPE; - break; - } - case 180: - { - windowOrientation = Dali::Window::PORTRAIT_INVERSE; - break; - } - case 270: - { - windowOrientation = Dali::Window::LANDSCAPE_INVERSE; - break; - } - default: - { - windowOrientation = Dali::Window::PORTRAIT; - break; - } - } - - ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) ); - wlSurface->RequestRotation( windowOrientation, width, height ); + mAdaptor->SurfaceResizeComplete( Dali::Adaptor::SurfaceSize( width, height ) ); } unsigned int Window::GetSupportedAuxiliaryHintCount() @@ -1475,10 +1446,12 @@ void Window::SetSize( Dali::DevelWindow::WindowSize size ) mSurface->MoveResize( positionSize ); - mAdaptor->SurfaceSizeChanged( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); + mAdaptor->SurfaceResizePrepare( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); // Emit signal mResizedSignal.Emit( Dali::DevelWindow::WindowSize( positionSize.width, positionSize.height ) ); + + mAdaptor->SurfaceResizeComplete( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); } } diff --git a/adaptors/ecore/wayland/window-render-surface-ecore-wl.cpp b/adaptors/ecore/wayland/window-render-surface-ecore-wl.cpp index 1df0faa..db97cd5 100644 --- a/adaptors/ecore/wayland/window-render-surface-ecore-wl.cpp +++ b/adaptors/ecore/wayland/window-render-surface-ecore-wl.cpp @@ -27,7 +27,6 @@ // INTERNAL INCLUDES #include #include -#include #include #include @@ -45,7 +44,6 @@ namespace { 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 @@ -54,16 +52,17 @@ WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize, 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 ), + mRotationAngle( 0 ), + mScreenRotationAngle( 0 ), mRotationSupported( false ), - mRotated( false ) + mRotationFinished( true ), + mScreenRotationFinished( true ), + mResizeFinished( true ) { DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" ); Init( surface ); @@ -87,10 +86,6 @@ WindowRenderSurface::~WindowRenderSurface() delete mRotationTrigger; } - if( mLibHandle != NULL ) - { - dlclose( mLibHandle ); - } } Ecore_Wl_Window* WindowRenderSurface::GetDrawable() @@ -110,7 +105,7 @@ Ecore_Wl_Window* WindowRenderSurface::GetWlWindow() return mWlWindow; } -void WindowRenderSurface::RequestRotation( Dali::Window::WindowOrientation orientation, int width, int height ) +void WindowRenderSurface::RequestRotation( int angle, int width, int height ) { if( !mRotationSupported ) { @@ -118,62 +113,42 @@ void WindowRenderSurface::RequestRotation( Dali::Window::WindowOrientation orien 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 ); } - 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 ) @@ -196,57 +171,28 @@ void WindowRenderSurface::CreateEglSurface( EglInterface& eglIf ) Internal::Adaptor::EglImplementation& eglImpl = static_cast( 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 { - 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 - 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 ) @@ -273,17 +219,17 @@ bool WindowRenderSurface::ReplaceEGLSurface( EglInterface& egl ) 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 { - 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( egl ); EGLNativeWindowType windowType( mEglWindow ); @@ -296,33 +242,32 @@ void WindowRenderSurface::MoveResize( Dali::PositionSize positionSize ) 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 - 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; } - if(needToMove) + if( needToMove ) { ecore_wl_window_position_set( mWlWindow, positionSize.x, positionSize.y ); } - if (needToResize) + if( needToResize ) { 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() @@ -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; } -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" ); @@ -385,16 +425,16 @@ void WindowRenderSurface::SetViewMode( ViewMode viewMode ) 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 - 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 ) { @@ -402,6 +442,27 @@ void WindowRenderSurface::CreateWlRenderable() } 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 ) @@ -423,7 +484,7 @@ void WindowRenderSurface::ReleaseLock() void WindowRenderSurface::ProcessRotationRequest() { - mRotated = false; + mRotationFinished = true; ecore_wl_window_rotation_change_done_send( mWlWindow ); diff --git a/adaptors/ecore/wayland/window-render-surface.h b/adaptors/ecore/wayland/window-render-surface.h index aa4eb9b..969141b 100644 --- a/adaptors/ecore/wayland/window-render-surface.h +++ b/adaptors/ecore/wayland/window-render-surface.h @@ -23,7 +23,6 @@ // INTERNAL INCLUDES #include -#include #include namespace Dali @@ -81,11 +80,16 @@ public: // API /** * Request surface rotation - * @param[in] orientation A new orientation of the surface + * @param[in] angle A new angle of the surface * @param[in] width A new width of the surface * @param[in] height A new height of the surface */ - void RequestRotation( Dali::Window::WindowOrientation orientation, int width, int height ); + void RequestRotation( int angle, int width, int height ); + + /** + * Notify output is transformed. + */ + void OutputTransformed(); /** * @brief Sets whether the surface is transparent or not. @@ -134,12 +138,12 @@ public: // from Dali::RenderSurface /** * @copydoc Dali::RenderSurface::PreRender() */ - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ); + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::PostRender() */ - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ); + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::StopRender() @@ -177,20 +181,17 @@ private: private: // Data - typedef int (*EglWinGetCapabilitiesFunction)( wl_egl_window* eglWindow ); - typedef int (*EglWinSetRotationFunction)( wl_egl_window* eglWindow, int rotation ); - - EglWinGetCapabilitiesFunction mEglWinGetCapabilitiesPtr; - EglWinSetRotationFunction mEglWinSetRotationPtr; - - void* mLibHandle; ///< Handle for the loaded library Ecore_Wl_Window* mWlWindow; ///< Wayland-Window wl_surface* mWlSurface; wl_egl_window* mEglWindow; ThreadSynchronizationInterface* mThreadSynchronization; TriggerEventInterface* mRotationTrigger; + int mRotationAngle; + int mScreenRotationAngle; bool mRotationSupported; - bool mRotated; + bool mRotationFinished; + bool mScreenRotationFinished; + bool mResizeFinished; }; // class WindowRenderSurface diff --git a/adaptors/integration-api/adaptor.h b/adaptors/integration-api/adaptor.h index 1d023ad..08d7f4b 100644 --- a/adaptors/integration-api/adaptor.h +++ b/adaptors/integration-api/adaptor.h @@ -339,11 +339,6 @@ public: */ void SetStereoBase( float stereoBase ); - /** - * @brief Informs core the surface size has changed - */ - void SurfaceSizeChanged( SurfaceSize surfaceSize ); - public: // Signals /** diff --git a/adaptors/integration-api/wayland/ecore-wl-render-surface.h b/adaptors/integration-api/wayland/ecore-wl-render-surface.h index aa747c4..e207082 100644 --- a/adaptors/integration-api/wayland/ecore-wl-render-surface.h +++ b/adaptors/integration-api/wayland/ecore-wl-render-surface.h @@ -2,7 +2,7 @@ #define __DALI_ECORE_WL_RENDER_SURFACE_H__ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -134,12 +134,12 @@ public: // from Dali::RenderSurface /** * @copydoc Dali::RenderSurface::PreRender() */ - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ) = 0; + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ) = 0; /** * @copydoc Dali::RenderSurface::PostRender() */ - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ) = 0; + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) = 0; /** * @copydoc Dali::RenderSurface::ReleaseLock() @@ -175,7 +175,7 @@ protected: protected: // Data - PositionSize mPosition; ///< Position + PositionSize mPositionSize; ///< Position std::string mTitle; ///< Title of window which shows from "xinfo -topvwins" command TriggerEventInterface* mRenderNotification; ///< Render notification trigger ColorDepth mColorDepth; ///< Color depth of surface (32 bit or 24 bit) diff --git a/adaptors/integration-api/wayland/native-render-surface.h b/adaptors/integration-api/wayland/native-render-surface.h index 3b0cd42..11e01e1 100644 --- a/adaptors/integration-api/wayland/native-render-surface.h +++ b/adaptors/integration-api/wayland/native-render-surface.h @@ -130,12 +130,12 @@ public: // from Dali::RenderSurface /** * @copydoc Dali::RenderSurface::PreRender() */ - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ); + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::PostRender() */ - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ); + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::StopRender() diff --git a/adaptors/integration-api/wayland/pixmap-render-surface.h b/adaptors/integration-api/wayland/pixmap-render-surface.h index 190e1ae..69d1de7 100644 --- a/adaptors/integration-api/wayland/pixmap-render-surface.h +++ b/adaptors/integration-api/wayland/pixmap-render-surface.h @@ -95,12 +95,12 @@ public: // from Dali::RenderSurface /** * @copydoc Dali::RenderSurface::PreRender() */ - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ); + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::PostRender() */ - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ); + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::StopRender() diff --git a/adaptors/integration-api/x11/ecore-x-render-surface.h b/adaptors/integration-api/x11/ecore-x-render-surface.h index 3f9b97c..8b1a0bf 100644 --- a/adaptors/integration-api/x11/ecore-x-render-surface.h +++ b/adaptors/integration-api/x11/ecore-x-render-surface.h @@ -142,12 +142,12 @@ public: // from Dali::RenderSurface /** * @copydoc Dali::RenderSurface::PreRender() */ - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ) = 0; + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ) = 0; /** * @copydoc Dali::RenderSurface::PostRender() */ - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ) = 0; + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) = 0; /** * @copydoc Dali::RenderSurface::ReleaseLock() diff --git a/adaptors/integration-api/x11/pixmap-render-surface.h b/adaptors/integration-api/x11/pixmap-render-surface.h index f31a0c7..106c90c 100644 --- a/adaptors/integration-api/x11/pixmap-render-surface.h +++ b/adaptors/integration-api/x11/pixmap-render-surface.h @@ -95,12 +95,12 @@ public: // from Dali::RenderSurface /** * @copydoc Dali::RenderSurface::PreRender() */ - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ); + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::PostRender() */ - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ); + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::StopRender() diff --git a/adaptors/tizen/native-render-surface-tizen.cpp b/adaptors/tizen/native-render-surface-tizen.cpp index 7af6a74..0bd6b7a 100644 --- a/adaptors/tizen/native-render-surface-tizen.cpp +++ b/adaptors/tizen/native-render-surface-tizen.cpp @@ -159,13 +159,13 @@ void NativeRenderSurface::StartRender() { } -bool NativeRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& ) +bool NativeRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction&, bool ) { // nothing to do for pixmaps return true; } -void NativeRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ) +void NativeRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) { Internal::Adaptor::EglImplementation& eglImpl = static_cast( egl ); eglImpl.SwapBuffers(); diff --git a/adaptors/wayland/render-surface/render-surface-wl.cpp b/adaptors/wayland/render-surface/render-surface-wl.cpp index e2c83cd..801a3bb 100644 --- a/adaptors/wayland/render-surface/render-surface-wl.cpp +++ b/adaptors/wayland/render-surface/render-surface-wl.cpp @@ -127,12 +127,12 @@ void RenderSurface::StartRender() { } -bool RenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& ) +bool RenderSurface::PreRender( EglInterface&, Integration::GlAbstraction&, bool ) { return true; } -void RenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ) +void RenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) { Internal::Adaptor::EglImplementation& eglImpl = static_cast( egl ); eglImpl.SwapBuffers(); diff --git a/adaptors/wayland/render-surface/render-surface-wl.h b/adaptors/wayland/render-surface/render-surface-wl.h index bbbf4d2..725c133 100644 --- a/adaptors/wayland/render-surface/render-surface-wl.h +++ b/adaptors/wayland/render-surface/render-surface-wl.h @@ -139,12 +139,12 @@ public: // from Dali::RenderSurface /** * @copydoc Dali::RenderSurface::PreRender() */ - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ); + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::PostRender() */ - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ); + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::StopRender(); diff --git a/adaptors/wayland/window-impl-wl.cpp b/adaptors/wayland/window-impl-wl.cpp index 4683b4c..ab267c2 100644 --- a/adaptors/wayland/window-impl-wl.cpp +++ b/adaptors/wayland/window-impl-wl.cpp @@ -418,10 +418,12 @@ void Window::SetSize( Dali::DevelWindow::WindowSize size ) mSurface->MoveResize( positionSize ); - mAdaptor->SurfaceSizeChanged( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); + mAdaptor->SurfaceResizePrepare( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); // Emit signal mResizedSignal.Emit( Dali::DevelWindow::WindowSize( positionSize.width, positionSize.height ) ); + + mAdaptor->SurfaceResizeComplete( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); } } diff --git a/adaptors/x11/pixmap-render-surface-x.cpp b/adaptors/x11/pixmap-render-surface-x.cpp index 76a8734..a5cf8db 100644 --- a/adaptors/x11/pixmap-render-surface-x.cpp +++ b/adaptors/x11/pixmap-render-surface-x.cpp @@ -194,13 +194,13 @@ void PixmapRenderSurface::StartRender() { } -bool PixmapRenderSurface::PreRender( EglInterface& egl, Integration::GlAbstraction& ) +bool PixmapRenderSurface::PreRender( EglInterface& egl, Integration::GlAbstraction&, bool ) { // Nothing to do for pixmaps return true; } -void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ) +void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) { // flush gl instruction queue glAbstraction.Flush(); diff --git a/adaptors/x11/window-impl-x.cpp b/adaptors/x11/window-impl-x.cpp index 92e6f74..5d2148f 100644 --- a/adaptors/x11/window-impl-x.cpp +++ b/adaptors/x11/window-impl-x.cpp @@ -808,6 +808,13 @@ void Window::RotationDone( int orientation, int width, int height ) ecore_x_window_prop_property_set( ecoreWindow, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE, ECORE_X_ATOM_CARDINAL, 32, &angles, 2 ); + + mAdaptor->SurfaceResizePrepare( Dali::Adaptor::SurfaceSize( width, height ) ); + + // Emit signal + mResizedSignal.Emit( Dali::DevelWindow::WindowSize( width, height ) ); + + mAdaptor->SurfaceResizeComplete( Dali::Adaptor::SurfaceSize( width, height ) ); #endif // DALI_PROFILE_UBUNTU } } @@ -912,10 +919,12 @@ void Window::SetSize( Dali::DevelWindow::WindowSize size ) mSurface->MoveResize( positionSize ); - mAdaptor->SurfaceSizeChanged( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); + mAdaptor->SurfaceResizePrepare( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); // Emit signal mResizedSignal.Emit( Dali::DevelWindow::WindowSize( positionSize.width, positionSize.height ) ); + + mAdaptor->SurfaceResizeComplete( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); } } diff --git a/adaptors/x11/window-render-surface-x.cpp b/adaptors/x11/window-render-surface-x.cpp index af29020..9954f9a 100644 --- a/adaptors/x11/window-render-surface-x.cpp +++ b/adaptors/x11/window-render-surface-x.cpp @@ -183,13 +183,13 @@ void WindowRenderSurface::StartRender() { } -bool WindowRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& ) +bool WindowRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction&, bool ) { // nothing to do for windows 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 ) { Internal::Adaptor::EglImplementation& eglImpl = static_cast( egl ); eglImpl.SwapBuffers(); diff --git a/adaptors/x11/window-render-surface.h b/adaptors/x11/window-render-surface.h index f9b5b41..c3bf335 100644 --- a/adaptors/x11/window-render-surface.h +++ b/adaptors/x11/window-render-surface.h @@ -122,12 +122,12 @@ public: // from Dali::RenderSurface /** * @copydoc Dali::RenderSurface::PreRender() */ - virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ); + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::PostRender() */ - virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface ); + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ); /** * @copydoc Dali::RenderSurface::StopRender()