X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fwindow-system%2Fcommon%2Fwindow-render-surface.cpp;h=509c174c96e7393b23eba0c9abd1115a1298177e;hb=0a170dd5b908a2316989ba82ca5c62ecfc347cee;hp=dacb89e7b74ddc630f073ee8e5dffeee8d3c62e9;hpb=94c641cee7e33a291d709283ee667953350ddae4;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/window-system/common/window-render-surface.cpp b/dali/internal/window-system/common/window-render-surface.cpp index dacb89e..509c174 100644 --- a/dali/internal/window-system/common/window-render-surface.cpp +++ b/dali/internal/window-system/common/window-render-surface.cpp @@ -60,11 +60,13 @@ WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize, Any s mThreadSynchronization( NULL ), mRenderNotification( NULL ), mRotationTrigger( NULL ), + mFrameRenderedTrigger(), mGraphics( nullptr ), mEGLSurface( nullptr ), mEGLContext( nullptr ), mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ), mOutputTransformedSignal(), + mFrameCallbackInfoContainer(), mRotationAngle( 0 ), mScreenRotationAngle( 0 ), mOwnSurface( false ), @@ -104,6 +106,13 @@ void WindowRenderSurface::Initialize( Any surface ) // Connect signals mWindowBase->OutputTransformedSignal().Connect( this, &WindowRenderSurface::OutputTransformed ); + + // Check screen rotation + mScreenRotationAngle = mWindowBase->GetScreenRotationAngle(); + if( mScreenRotationAngle != 0 ) + { + mScreenRotationFinished = false; + } } Any WindowRenderSurface::GetNativeWindow() @@ -133,6 +142,12 @@ void WindowRenderSurface::SetTransparency( bool transparent ) void WindowRenderSurface::RequestRotation( int angle, int width, int height ) { + if( !mRotationSupported ) + { + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: Rotation is not supported!\n" ); + return; + } + if( !mRotationTrigger ) { mRotationTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ); @@ -184,11 +199,6 @@ void WindowRenderSurface::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpi dpiVertical = mDpiVertical; } -int WindowRenderSurface::GetOrientation() const -{ - return mWindowBase->GetOrientation(); -} - void WindowRenderSurface::InitializeGraphics() { mGraphics = &mAdaptor->GetGraphicsInterface(); @@ -214,8 +224,20 @@ void WindowRenderSurface::CreateSurface() { DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + int width, height; + if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 ) + { + width = mPositionSize.width; + height = mPositionSize.height; + } + else + { + width = mPositionSize.height; + height = mPositionSize.width; + } + // Create the EGL window - EGLNativeWindowType window = mWindowBase->CreateEglWindow( mPositionSize.width, mPositionSize.height ); + EGLNativeWindowType window = mWindowBase->CreateEglWindow( width, height ); auto eglGraphics = static_cast(mGraphics); @@ -332,17 +354,77 @@ void WindowRenderSurface::StartRender() { } -bool WindowRenderSurface::PreRender( bool resizingSurface ) +bool WindowRenderSurface::PreRender( bool resizingSurface, const std::vector>& damagedRects, Rect& clippingRect ) { + Dali::Integration::Scene::FrameCallbackContainer callbacks; + + Dali::Integration::Scene scene = mScene.GetHandle(); + if( scene ) + { + scene.GetFrameRenderedCallback( callbacks ); + if( !callbacks.empty() ) + { + int frameRenderedSync = mWindowBase->CreateFrameRenderedSyncFence(); + if( frameRenderedSync != -1 ) + { + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: CreateFrameRenderedSyncFence [%d]\n", frameRenderedSync ); + + mFrameCallbackInfoContainer.push_back( std::unique_ptr< FrameCallbackInfo >( new FrameCallbackInfo( callbacks, frameRenderedSync ) ) ); + + if( !mFrameRenderedTrigger ) + { + mFrameRenderedTrigger = std::unique_ptr< TriggerEventInterface >( TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessFrameCallback ), + TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) ); + } + mFrameRenderedTrigger->Trigger(); + } + else + { + DALI_LOG_ERROR( "WindowRenderSurface::PreRender: CreateFrameRenderedSyncFence is failed\n" ); + } + + // Clear callbacks + callbacks.clear(); + } + + scene.GetFramePresentedCallback( callbacks ); + if( !callbacks.empty() ) + { + int framePresentedSync = mWindowBase->CreateFramePresentedSyncFence(); + if( framePresentedSync != -1 ) + { + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: CreateFramePresentedSyncFence [%d]\n", framePresentedSync ); + + mFrameCallbackInfoContainer.push_back( std::unique_ptr< FrameCallbackInfo >( new FrameCallbackInfo( callbacks, framePresentedSync ) ) ); + + if( !mFrameRenderedTrigger ) + { + mFrameRenderedTrigger = std::unique_ptr< TriggerEventInterface >( TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessFrameCallback ), + TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) ); + } + mFrameRenderedTrigger->Trigger(); + } + else + { + DALI_LOG_ERROR( "WindowRenderSurface::PreRender: CreateFramePresentedSyncFence is failed\n" ); + } + + // Clear callbacks + callbacks.clear(); + } + } + MakeContextCurrent(); + auto eglGraphics = static_cast(mGraphics); + if( resizingSurface ) { - int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360; - // Window rotate or screen rotate if( !mRotationFinished || !mScreenRotationFinished ) { + int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360; + mWindowBase->SetEglWindowRotation( totalAngle ); mWindowBase->SetEglWindowBufferTransform( totalAngle ); @@ -359,39 +441,31 @@ bool WindowRenderSurface::PreRender( bool resizingSurface ) } // Resize case - if ( !mResizeFinished ) + if( !mResizeFinished ) { - Dali::PositionSize positionSize; - positionSize.x = mPositionSize.x; - positionSize.y = mPositionSize.y; - if( totalAngle == 0 || totalAngle == 180 ) - { - positionSize.width = mPositionSize.width; - positionSize.height = mPositionSize.height; - } - else - { - positionSize.width = mPositionSize.height; - positionSize.height = mPositionSize.width; - } - mWindowBase->ResizeEglWindow( positionSize ); + mWindowBase->ResizeEglWindow( mPositionSize ); mResizeFinished = true; DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set resize\n" ); } + + if (eglGraphics) + { + Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); + eglImpl.SetFullSwapNextFrame(); + } } - auto eglGraphics = static_cast(mGraphics); - if ( eglGraphics ) + if (eglGraphics) { - GlImplementation& mGLES = eglGraphics->GetGlesInterface(); - mGLES.PreRender(); + Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); + eglImpl.SetDamage( mEGLSurface, damagedRects, clippingRect ); } return true; } -void WindowRenderSurface::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ) +void WindowRenderSurface::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector>& damagedRects ) { // Inform the gl implementation that rendering has finished before informing the surface auto eglGraphics = static_cast(mGraphics); @@ -431,7 +505,7 @@ void WindowRenderSurface::PostRender( bool renderToFbo, bool replacingSurface, b } Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); - eglImpl.SwapBuffers( mEGLSurface ); + eglImpl.SwapBuffers( mEGLSurface, damagedRects ); if( mRenderNotification ) { @@ -487,15 +561,14 @@ void WindowRenderSurface::OutputTransformed() { mScreenRotationAngle = screenRotationAngle; mScreenRotationFinished = false; - mResizeFinished = false; mOutputTransformedSignal.Emit(); - DALI_LOG_RELEASE_INFO( "WindowRenderSurface::OutputTransformed: window = %d screen = %d\n", mRotationAngle, mScreenRotationAngle ); + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::OutputTransformed: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle ); } else { - DALI_LOG_RELEASE_INFO( "WindowRenderSurface::OutputTransformed: Ignore output transform [%d]\n", mScreenRotationAngle ); + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::OutputTransformed: Ignore output transform [%d]\n", mScreenRotationAngle ); } } @@ -513,6 +586,47 @@ void WindowRenderSurface::ProcessRotationRequest() } } +void WindowRenderSurface::ProcessFrameCallback() +{ + for( auto&& iter : mFrameCallbackInfoContainer ) + { + if( !iter->fileDescriptorMonitor ) + { + iter->fileDescriptorMonitor = std::unique_ptr< FileDescriptorMonitor >( new FileDescriptorMonitor( iter->fileDescriptor, + MakeCallback( this, &WindowRenderSurface::OnFileDescriptorEventDispatched ), FileDescriptorMonitor::FD_READABLE ) ); + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::ProcessFrameCallback: Add handler [%d]\n", iter->fileDescriptor ); + } + } +} + +void WindowRenderSurface::OnFileDescriptorEventDispatched( FileDescriptorMonitor::EventType eventBitMask, int fileDescriptor ) +{ + if( !( eventBitMask & FileDescriptorMonitor::FD_READABLE ) ) + { + DALI_LOG_ERROR( "WindowRenderSurface::OnFileDescriptorEventDispatched: file descriptor error [%d]\n", eventBitMask ); + close( fileDescriptor ); + return; + } + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::OnFileDescriptorEventDispatched: Frame rendered [%d]\n", fileDescriptor ); + + auto frameCallbackInfo = std::find_if( mFrameCallbackInfoContainer.begin(), mFrameCallbackInfoContainer.end(), + [fileDescriptor]( std::unique_ptr< FrameCallbackInfo >& callbackInfo ) + { + return callbackInfo->fileDescriptor == fileDescriptor; + } ); + if( frameCallbackInfo != mFrameCallbackInfoContainer.end() ) + { + // Call the connected callback + for( auto&& iter : ( *frameCallbackInfo )->callbacks ) + { + CallbackBase::Execute( *( iter.first ), iter.second ); + } + mFrameCallbackInfoContainer.erase( frameCallbackInfo ); + } +} + } // namespace Adaptor } // namespace internal