X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fwindow-system%2Fcommon%2Fwindow-render-surface.cpp;h=b1ba7a15ef25ba61904be34a4977967d1f49a9e2;hb=c16dd2637c2221f603cdccbe0db4788cc856a769;hp=d92c5dca8805afdfb344eda283caf9b0b0d9787e;hpb=8c6d4c7f10c1f7301531b12af584171dfb1823f3;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 d92c5dc..b1ba7a1 100644 --- a/dali/internal/window-system/common/window-render-surface.cpp +++ b/dali/internal/window-system/common/window-render-surface.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,8 @@ #include // EXTERNAL INCLUDES -#include #include +#include // INTERNAL INCLUDES #include @@ -29,10 +29,10 @@ #include #include #include +#include #include #include #include -#include namespace Dali { @@ -40,25 +40,23 @@ namespace Internal { namespace Adaptor { - namespace { - -const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved -const float FULL_UPDATE_RATIO( 0.8f ); ///< Force full update when the dirty area is larget than this ratio +const int MINIMUM_DIMENSION_CHANGE(1); ///< Minimum change for window to be considered to have moved +const float FULL_UPDATE_RATIO(0.8f); ///< Force full update when the dirty area is larget than this ratio #if defined(DEBUG_ENABLED) Debug::Filter* gWindowRenderSurfaceLogFilter = Debug::Filter::New(Debug::Verbose, false, "LOG_WINDOW_RENDER_SURFACE"); #endif -void MergeRects( Rect< int >& mergingRect, const std::vector< Rect< int > >& rects ) +void MergeRects(Rect& mergingRect, const std::vector>& rects) { uint32_t i = 0; - if( mergingRect.IsEmpty() ) + if(mergingRect.IsEmpty()) { - for( ; i < rects.size(); i++ ) + for(; i < rects.size(); i++) { - if( !rects[i].IsEmpty() ) + if(!rects[i].IsEmpty()) { mergingRect = rects[i]; break; @@ -66,21 +64,60 @@ void MergeRects( Rect< int >& mergingRect, const std::vector< Rect< int > >& rec } } - for( ; i < rects.size(); i++ ) + for(; i < rects.size(); i++) { - mergingRect.Merge( rects[i] ); + mergingRect.Merge(rects[i]); } } -void InsertRects( WindowRenderSurface::DamagedRectsContainer& damagedRectsList, const std::vector< Rect< int > >& damagedRects ) +void InsertRects(WindowRenderSurface::DamagedRectsContainer& damagedRectsList, const std::vector>& damagedRects) { - damagedRectsList.push_front( damagedRects ); - if( damagedRectsList.size() > 4 ) // past triple buffers + current + damagedRectsList.push_front(damagedRects); + if(damagedRectsList.size() > 4) // past triple buffers + current { damagedRectsList.pop_back(); } } +Rect RecalculateRect0(Rect& rect, const Rect& surfaceSize) +{ + return rect; +} + +Rect RecalculateRect90(Rect& rect, const Rect& surfaceSize) +{ + Rect newRect; + newRect.x = surfaceSize.height - (rect.y + rect.height); + newRect.y = rect.x; + newRect.width = rect.height; + newRect.height = rect.width; + return newRect; +} + +Rect RecalculateRect180(Rect& rect, const Rect& surfaceSize) +{ + Rect newRect; + newRect.x = surfaceSize.width - (rect.x + rect.width); + newRect.y = surfaceSize.height - (rect.y + rect.height); + newRect.width = rect.width; + newRect.height = rect.height; + return newRect; +} + +Rect RecalculateRect270(Rect& rect, const Rect& surfaceSize) +{ + Rect newRect; + newRect.x = rect.y; + newRect.y = surfaceSize.width - (rect.x + rect.width); + newRect.width = rect.height; + newRect.height = rect.width; + return newRect; +} + +using RecalculateRectFunction = Rect (*)(Rect&, const Rect&); + +RecalculateRectFunction RecalculateRect[4] = {RecalculateRect0, RecalculateRect90, RecalculateRect180, RecalculateRect270}; + } // unnamed namespace WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any surface, bool isTransparent) @@ -90,7 +127,7 @@ WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any su mWindowBase(), mThreadSynchronization(nullptr), mRenderNotification(nullptr), - mRotationTrigger(nullptr), + mPostRenderTrigger(), mFrameRenderedTrigger(), mGraphics(nullptr), mEGLSurface(nullptr), @@ -108,46 +145,43 @@ WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any su mWindowRotationFinished(true), mScreenRotationFinished(true), mResizeFinished(true), - mDefaultScreenRotationAvailable(false) + mDefaultScreenRotationAvailable(false), + mIsImeWindowSurface(false) { - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" ); - Initialize( surface ); + DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n"); + Initialize(surface); } WindowRenderSurface::~WindowRenderSurface() { - if( mRotationTrigger ) - { - delete mRotationTrigger; - } } -void WindowRenderSurface::Initialize( Any surface ) +void WindowRenderSurface::Initialize(Any surface) { // If width or height are zero, go full screen. - if ( (mPositionSize.width == 0) || (mPositionSize.height == 0) ) + if((mPositionSize.width == 0) || (mPositionSize.height == 0)) { // Default window size == screen size mPositionSize.x = 0; mPositionSize.y = 0; - WindowSystem::GetScreenSize( mPositionSize.width, mPositionSize.height ); + WindowSystem::GetScreenSize(mPositionSize.width, mPositionSize.height); } // Create a window base auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory(); - mWindowBase = windowFactory->CreateWindowBase( mPositionSize, surface, ( mColorDepth == COLOR_DEPTH_32 ? true : false ) ); + mWindowBase = windowFactory->CreateWindowBase(mPositionSize, surface, (mColorDepth == COLOR_DEPTH_32 ? true : false)); // Connect signals - mWindowBase->OutputTransformedSignal().Connect( this, &WindowRenderSurface::OutputTransformed ); + mWindowBase->OutputTransformedSignal().Connect(this, &WindowRenderSurface::OutputTransformed); // Check screen rotation mScreenRotationAngle = mWindowBase->GetScreenRotationAngle(); - if( mScreenRotationAngle != 0 ) + if(mScreenRotationAngle != 0) { - mScreenRotationFinished = false; - mResizeFinished = false; + mScreenRotationFinished = false; + mResizeFinished = false; mDefaultScreenRotationAvailable = true; - DALI_LOG_RELEASE_INFO("WindowRenderSurface::Initialize, screen rotation is enabled, screen rotation angle:[%d]\n", mScreenRotationAngle ); + DALI_LOG_RELEASE_INFO("WindowRenderSurface::Initialize, screen rotation is enabled, screen rotation angle:[%d]\n", mScreenRotationAngle); } } @@ -166,21 +200,22 @@ void WindowRenderSurface::Map() mWindowBase->Show(); } -void WindowRenderSurface::SetRenderNotification( TriggerEventInterface* renderNotification ) +void WindowRenderSurface::SetRenderNotification(TriggerEventInterface* renderNotification) { mRenderNotification = renderNotification; } -void WindowRenderSurface::SetTransparency( bool transparent ) +void WindowRenderSurface::SetTransparency(bool transparent) { - mWindowBase->SetTransparency( transparent ); + mWindowBase->SetTransparency(transparent); } void WindowRenderSurface::RequestRotation(int angle, int width, int height) { - if(!mRotationTrigger) + if(!mPostRenderTrigger) { - mRotationTrigger = TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &WindowRenderSurface::ProcessRotationRequest), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER); + mPostRenderTrigger = std::unique_ptr(TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &WindowRenderSurface::ProcessPostRender), + TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER)); } mPositionSize.width = width; @@ -188,6 +223,7 @@ void WindowRenderSurface::RequestRotation(int angle, int width, int height) mWindowRotationAngle = angle; mWindowRotationFinished = false; + mResizeFinished = false; mWindowBase->SetWindowRotationAngle(mWindowRotationAngle); @@ -209,24 +245,24 @@ PositionSize WindowRenderSurface::GetPositionSize() const return mPositionSize; } -void WindowRenderSurface::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) +void WindowRenderSurface::GetDpi(unsigned int& dpiHorizontal, unsigned int& dpiVertical) { - if( mDpiHorizontal == 0 || mDpiVertical == 0 ) + if(mDpiHorizontal == 0 || mDpiVertical == 0) { - const char* environmentDpiHorizontal = std::getenv( DALI_ENV_DPI_HORIZONTAL ); - mDpiHorizontal = environmentDpiHorizontal ? std::atoi( environmentDpiHorizontal ) : 0; + const char* environmentDpiHorizontal = std::getenv(DALI_ENV_DPI_HORIZONTAL); + mDpiHorizontal = environmentDpiHorizontal ? std::atoi(environmentDpiHorizontal) : 0; - const char* environmentDpiVertical = std::getenv( DALI_ENV_DPI_VERTICAL ); - mDpiVertical = environmentDpiVertical ? std::atoi( environmentDpiVertical ) : 0; + const char* environmentDpiVertical = std::getenv(DALI_ENV_DPI_VERTICAL); + mDpiVertical = environmentDpiVertical ? std::atoi(environmentDpiVertical) : 0; - if( mDpiHorizontal == 0 || mDpiVertical == 0 ) + if(mDpiHorizontal == 0 || mDpiVertical == 0) { - mWindowBase->GetDpi( mDpiHorizontal, mDpiVertical ); + mWindowBase->GetDpi(mDpiHorizontal, mDpiVertical); } } dpiHorizontal = mDpiHorizontal; - dpiVertical = mDpiVertical; + dpiVertical = mDpiVertical; } int WindowRenderSurface::GetOrientation() const @@ -238,17 +274,17 @@ void WindowRenderSurface::InitializeGraphics() { mGraphics = &mAdaptor->GetGraphicsInterface(); - DALI_ASSERT_ALWAYS( mGraphics && "Graphics interface is not created" ); + DALI_ASSERT_ALWAYS(mGraphics && "Graphics interface is not created"); - auto eglGraphics = static_cast(mGraphics); - mEGL = &eglGraphics->GetEglInterface(); + auto eglGraphics = static_cast(mGraphics); + mEGL = &eglGraphics->GetEglInterface(); - if ( mEGLContext == NULL ) + if(mEGLContext == NULL) { // Create the OpenGL context for this window Internal::Adaptor::EglImplementation& eglImpl = static_cast(*mEGL); eglImpl.ChooseConfig(true, mColorDepth); - eglImpl.CreateWindowContext( mEGLContext ); + eglImpl.CreateWindowContext(mEGLContext); // Create the OpenGL surface CreateSurface(); @@ -289,20 +325,20 @@ void WindowRenderSurface::CreateSurface() void WindowRenderSurface::DestroySurface() { - DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + DALI_LOG_TRACE_METHOD(gWindowRenderSurfaceLogFilter); - auto eglGraphics = static_cast(mGraphics); - if( eglGraphics ) + auto eglGraphics = static_cast(mGraphics); + if(eglGraphics) { - DALI_LOG_RELEASE_INFO("WindowRenderSurface::DestroySurface: WinId (%d)\n", mWindowBase->GetNativeWindowId() ); + DALI_LOG_RELEASE_INFO("WindowRenderSurface::DestroySurface: WinId (%d)\n", mWindowBase->GetNativeWindowId()); Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); - eglImpl.DestroySurface( mEGLSurface ); + eglImpl.DestroySurface(mEGLSurface); mEGLSurface = nullptr; // Destroy context also - eglImpl.DestroyContext( mEGLContext ); + eglImpl.DestroyContext(mEGLContext); mEGLContext = nullptr; mWindowBase->DestroyEglWindow(); @@ -311,79 +347,79 @@ void WindowRenderSurface::DestroySurface() bool WindowRenderSurface::ReplaceGraphicsSurface() { - DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + DALI_LOG_TRACE_METHOD(gWindowRenderSurfaceLogFilter); // Destroy the old one mWindowBase->DestroyEglWindow(); int width, height; - if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 ) + if(mScreenRotationAngle == 0 || mScreenRotationAngle == 180) { - width = mPositionSize.width; + width = mPositionSize.width; height = mPositionSize.height; } else { - width = mPositionSize.height; + width = mPositionSize.height; height = mPositionSize.width; } // Create the EGL window - EGLNativeWindowType window = mWindowBase->CreateEglWindow( width, height ); + EGLNativeWindowType window = mWindowBase->CreateEglWindow(width, height); // Set screen rotation mScreenRotationFinished = false; - auto eglGraphics = static_cast(mGraphics); + auto eglGraphics = static_cast(mGraphics); Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); - return eglImpl.ReplaceSurfaceWindow( window, mEGLSurface, mEGLContext ); + return eglImpl.ReplaceSurfaceWindow(window, mEGLSurface, mEGLContext); } -void WindowRenderSurface::MoveResize( Dali::PositionSize positionSize ) +void WindowRenderSurface::MoveResize(Dali::PositionSize positionSize) { - bool needToMove = false; + 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) ) + if((fabs(positionSize.x - mPositionSize.x) >= MINIMUM_DIMENSION_CHANGE) || + (fabs(positionSize.y - mPositionSize.y) >= MINIMUM_DIMENSION_CHANGE)) { needToMove = true; } // Check resizing - if( (fabs(positionSize.width - mPositionSize.width) > MINIMUM_DIMENSION_CHANGE) || - (fabs(positionSize.height - mPositionSize.height) > MINIMUM_DIMENSION_CHANGE) ) + if((fabs(positionSize.width - mPositionSize.width) >= MINIMUM_DIMENSION_CHANGE) || + (fabs(positionSize.height - mPositionSize.height) >= MINIMUM_DIMENSION_CHANGE)) { needToResize = true; } - if( needToResize ) + if(needToResize) { - if( needToMove ) + if(needToMove) { - mWindowBase->MoveResize( positionSize ); + mWindowBase->MoveResize(positionSize); } else { - mWindowBase->Resize( positionSize ); + mWindowBase->Resize(positionSize); } mResizeFinished = false; - mPositionSize = positionSize; + mPositionSize = positionSize; } else { - if( needToMove ) + if(needToMove) { - mWindowBase->Move( positionSize ); + mWindowBase->Move(positionSize); mPositionSize = positionSize; } } - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height ); + DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height); } void WindowRenderSurface::StartRender() @@ -392,6 +428,8 @@ void WindowRenderSurface::StartRender() bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector>& damagedRects, Rect& clippingRect) { + mDamagedRects.assign(damagedRects.begin(), damagedRects.end()); + Dali::Integration::Scene::FrameCallbackContainer callbacks; Dali::Integration::Scene scene = mScene.GetHandle(); @@ -407,7 +445,7 @@ bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector(new FrameCallbackInfo(callbacks, frameRenderedSync))); @@ -430,7 +468,7 @@ bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector(new FrameCallbackInfo(callbacks, framePresentedSync))); @@ -456,8 +494,6 @@ bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector PreRotation * wl_egl_window_tizen_set_buffer_transform(SetEglWindowBufferTransform) -> Screen Rotation @@ -467,7 +503,7 @@ bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vectorResizeEglWindow(positionSize); mResizeFinished = true; - DALI_LOG_RELEASE_INFO("WindowRenderSurface::PreRender: Set resize\n"); + DALI_LOG_RELEASE_INFO("WindowRenderSurface::PreRender: Set resize, x: %d, y: %d, w: %d, h:%d\n", positionSize.x, positionSize.y, positionSize.width, positionSize.height); } SetFullSwapNextFrame(); mDefaultScreenRotationAvailable = false; } - SetBufferDamagedRects(damagedRects, clippingRect); + SetBufferDamagedRects(mDamagedRects, clippingRect); + + if(clippingRect.IsEmpty()) + { + mDamagedRects.clear(); + } + + // This is now done when the render pass for the render surface begins + // MakeContextCurrent(); return true; } -void WindowRenderSurface::PostRender(bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector>& damagedRects) +void WindowRenderSurface::PostRender() { // Inform the gl implementation that rendering has finished before informing the surface auto eglGraphics = static_cast(mGraphics); @@ -528,37 +572,27 @@ void WindowRenderSurface::PostRender(bool renderToFbo, bool replacingSurface, bo GlImplementation& mGLES = eglGraphics->GetGlesInterface(); mGLES.PostRender(); - if(renderToFbo) + if((mIsResizing && !mWindowRotationFinished) || mIsImeWindowSurface) { - mGLES.Flush(); - mGLES.Finish(); - } - else - { - if(resizingSurface) + if(mThreadSynchronization) { - if(!mWindowRotationFinished) - { - if(mThreadSynchronization) - { - // Enable PostRender flag - mThreadSynchronization->PostRenderStarted(); - } - - DALI_LOG_RELEASE_INFO("WindowRenderSurface::PostRender: Trigger rotation event\n"); + // Enable PostRender flag + mThreadSynchronization->PostRenderStarted(); + } - mRotationTrigger->Trigger(); + if(!mWindowRotationFinished || mIsImeWindowSurface) + { + mPostRenderTrigger->Trigger(); + } - if(mThreadSynchronization) - { - // Wait until the event-thread complete the rotation event processing - mThreadSynchronization->PostRenderWaitForCompletion(); - } - } + if(mThreadSynchronization) + { + // Wait until the event-thread complete the rotation event processing + mThreadSynchronization->PostRenderWaitForCompletion(); } } - SwapBuffers(damagedRects); + SwapBuffers(mDamagedRects); if(mRenderNotification) { @@ -571,9 +605,9 @@ void WindowRenderSurface::StopRender() { } -void WindowRenderSurface::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization ) +void WindowRenderSurface::SetThreadSynchronization(ThreadSynchronizationInterface& threadSynchronization) { - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::SetThreadSynchronization: called\n" ); + DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::SetThreadSynchronization: called\n"); mThreadSynchronization = &threadSynchronization; } @@ -590,9 +624,9 @@ Dali::RenderSurfaceInterface::Type WindowRenderSurface::GetSurfaceType() void WindowRenderSurface::MakeContextCurrent() { - if ( mEGL != nullptr ) + if(mEGL != nullptr) { - mEGL->MakeContextCurrent( mEGLSurface, mEGLContext ); + mEGL->MakeContextCurrent(mEGLSurface, mEGLContext); } } @@ -606,6 +640,16 @@ Integration::StencilBufferAvailable WindowRenderSurface::GetStencilBufferRequire return mGraphics ? mGraphics->GetStencilBufferRequired() : Integration::StencilBufferAvailable::FALSE; } +void WindowRenderSurface::InitializeImeSurface() +{ + mIsImeWindowSurface = true; + if(!mPostRenderTrigger) + { + mPostRenderTrigger = std::unique_ptr(TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &WindowRenderSurface::ProcessPostRender), + TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER)); + } +} + void WindowRenderSurface::OutputTransformed() { int screenRotationAngle = mWindowBase->GetScreenRotationAngle(); @@ -626,13 +670,19 @@ void WindowRenderSurface::OutputTransformed() } } -void WindowRenderSurface::ProcessRotationRequest() +void WindowRenderSurface::ProcessPostRender() { - mWindowRotationFinished = true; - - mWindowBase->WindowRotationCompleted(mWindowRotationAngle, mPositionSize.width, mPositionSize.height); + if(!mWindowRotationFinished) + { + mWindowBase->WindowRotationCompleted(mWindowRotationAngle, mPositionSize.width, mPositionSize.height); + DALI_LOG_RELEASE_INFO("WindowRenderSurface::ProcessPostRender: Rotation Done\n"); + mWindowRotationFinished = true; + } - DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::ProcessRotationRequest: Rotation Done\n"); + if(mIsImeWindowSurface) + { + mWindowBase->ImeWindowReadyToRender(); + } if(mThreadSynchronization) { @@ -642,185 +692,200 @@ void WindowRenderSurface::ProcessRotationRequest() void WindowRenderSurface::ProcessFrameCallback() { - Dali::Mutex::ScopedLock lock( mMutex ); + Dali::Mutex::ScopedLock lock(mMutex); - for( auto&& iter : mFrameCallbackInfoContainer ) + for(auto&& iter : mFrameCallbackInfoContainer) { - if( !iter->fileDescriptorMonitor ) + if(!iter->fileDescriptorMonitor) { - iter->fileDescriptorMonitor = std::unique_ptr< FileDescriptorMonitor >( new FileDescriptorMonitor( iter->fileDescriptor, - MakeCallback( this, &WindowRenderSurface::OnFileDescriptorEventDispatched ), FileDescriptorMonitor::FD_READABLE ) ); + iter->fileDescriptorMonitor = std::unique_ptr(new FileDescriptorMonitor(iter->fileDescriptor, + MakeCallback(this, &WindowRenderSurface::OnFileDescriptorEventDispatched), + FileDescriptorMonitor::FD_READABLE)); - DALI_LOG_RELEASE_INFO( "WindowRenderSurface::ProcessFrameCallback: Add handler [%d]\n", iter->fileDescriptor ); + DALI_LOG_RELEASE_INFO("WindowRenderSurface::ProcessFrameCallback: Add handler [%d]\n", iter->fileDescriptor); } } } -void WindowRenderSurface::OnFileDescriptorEventDispatched( FileDescriptorMonitor::EventType eventBitMask, int fileDescriptor ) +void WindowRenderSurface::OnFileDescriptorEventDispatched(FileDescriptorMonitor::EventType eventBitMask, int fileDescriptor) { - if( !( eventBitMask & FileDescriptorMonitor::FD_READABLE ) ) + if(!(eventBitMask & FileDescriptorMonitor::FD_READABLE)) { - DALI_LOG_ERROR( "WindowRenderSurface::OnFileDescriptorEventDispatched: file descriptor error [%d]\n", eventBitMask ); - close( fileDescriptor ); + DALI_LOG_ERROR("WindowRenderSurface::OnFileDescriptorEventDispatched: file descriptor error [%d]\n", eventBitMask); + close(fileDescriptor); return; } - DALI_LOG_RELEASE_INFO( "WindowRenderSurface::OnFileDescriptorEventDispatched: Frame rendered [%d]\n", fileDescriptor ); + DALI_LOG_RELEASE_INFO("WindowRenderSurface::OnFileDescriptorEventDispatched: Frame rendered [%d]\n", fileDescriptor); - std::unique_ptr< FrameCallbackInfo > callbackInfo; + std::unique_ptr callbackInfo; { - Dali::Mutex::ScopedLock lock( mMutex ); - auto frameCallbackInfo = std::find_if( mFrameCallbackInfoContainer.begin(), mFrameCallbackInfoContainer.end(), - [fileDescriptor]( std::unique_ptr< FrameCallbackInfo >& callbackInfo ) - { - return callbackInfo->fileDescriptor == fileDescriptor; - } ); - if( frameCallbackInfo != mFrameCallbackInfoContainer.end() ) + Dali::Mutex::ScopedLock lock(mMutex); + auto frameCallbackInfo = std::find_if(mFrameCallbackInfoContainer.begin(), mFrameCallbackInfoContainer.end(), [fileDescriptor](std::unique_ptr& callbackInfo) { + return callbackInfo->fileDescriptor == fileDescriptor; + }); + if(frameCallbackInfo != mFrameCallbackInfoContainer.end()) { - callbackInfo = std::move( *frameCallbackInfo ); + callbackInfo = std::move(*frameCallbackInfo); - mFrameCallbackInfoContainer.erase( frameCallbackInfo ); + mFrameCallbackInfoContainer.erase(frameCallbackInfo); } } // Call the connected callback - if( callbackInfo ) + if(callbackInfo) { - for( auto&& iter : ( callbackInfo )->callbacks ) + for(auto&& iter : (callbackInfo)->callbacks) { - CallbackBase::Execute( *( iter.first ), iter.second ); + CallbackBase::Execute(*(iter.first), iter.second); } } } -void WindowRenderSurface::SetBufferDamagedRects( const std::vector< Rect< int > >& damagedRects, Rect< int >& clippingRect ) +void WindowRenderSurface::SetBufferDamagedRects(const std::vector>& damagedRects, Rect& clippingRect) { - auto eglGraphics = static_cast< EglGraphics* >( mGraphics ); - if ( eglGraphics ) + auto eglGraphics = static_cast(mGraphics); + if(eglGraphics) { Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); - if( !eglImpl.IsPartialUpdateRequired() ) + if(!eglImpl.IsPartialUpdateRequired()) { return; } - Rect< int > surfaceRect( 0, 0, mPositionSize.width, mPositionSize.height ); + Rect surfaceRect(0, 0, mPositionSize.width, mPositionSize.height); - if( mFullSwapNextFrame ) + if(mFullSwapNextFrame) { - InsertRects( mBufferDamagedRects, std::vector< Rect< int > >( 1, surfaceRect ) ); - clippingRect = Rect< int >(); + InsertRects(mBufferDamagedRects, std::vector>(1, surfaceRect)); + clippingRect = Rect(); return; } - EGLint bufferAge = eglImpl.GetBufferAge( mEGLSurface ); + EGLint bufferAge = eglImpl.GetBufferAge(mEGLSurface); // Buffer age 0 means the back buffer in invalid and requires full swap - if( !damagedRects.size() || bufferAge == 0 ) + if(!damagedRects.size() || bufferAge == 0) { - InsertRects( mBufferDamagedRects, std::vector< Rect< int > >( 1, surfaceRect ) ); - clippingRect = Rect< int >(); + InsertRects(mBufferDamagedRects, std::vector>(1, surfaceRect)); + clippingRect = Rect(); return; } // We push current frame damaged rects here, zero index for current frame - InsertRects( mBufferDamagedRects, damagedRects ); + InsertRects(mBufferDamagedRects, damagedRects); // Merge damaged rects into clipping rect auto bufferDamagedRects = mBufferDamagedRects.begin(); - while( bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end() ) + while(bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end()) { - const std::vector< Rect< int > >& rects = *bufferDamagedRects++; - MergeRects( clippingRect, rects ); + const std::vector>& rects = *bufferDamagedRects++; + MergeRects(clippingRect, rects); } - if( !clippingRect.Intersect( surfaceRect ) || clippingRect.Area() > surfaceRect.Area() * FULL_UPDATE_RATIO ) + if(!clippingRect.Intersect(surfaceRect) || clippingRect.Area() > surfaceRect.Area() * FULL_UPDATE_RATIO) { // clipping area too big or doesn't intersect surface rect - clippingRect = Rect< int >(); + clippingRect = Rect(); return; } - std::vector< Rect< int > > damagedRegion; - damagedRegion.push_back( clippingRect ); + std::vector> damagedRegion; + Dali::Integration::Scene scene = mScene.GetHandle(); + if(scene) + { + damagedRegion.push_back(RecalculateRect[std::min(scene.GetCurrentSurfaceOrientation() / 90, 3)](clippingRect, scene.GetCurrentSurfaceRect())); + } + else + { + damagedRegion.push_back(clippingRect); + } - eglImpl.SetDamageRegion( mEGLSurface, damagedRegion ); + eglImpl.SetDamageRegion(mEGLSurface, damagedRegion); } } -void WindowRenderSurface::SwapBuffers( const std::vector>& damagedRects ) +void WindowRenderSurface::SwapBuffers(const std::vector>& damagedRects) { - auto eglGraphics = static_cast< EglGraphics* >( mGraphics ); - if( eglGraphics ) + auto eglGraphics = static_cast(mGraphics); + if(eglGraphics) { - Rect< int > surfaceRect( 0, 0, mPositionSize.width, mPositionSize.height ); + Rect surfaceRect; + int32_t orientation = 0; + + Dali::Integration::Scene scene = mScene.GetHandle(); + if(scene) + { + surfaceRect = scene.GetCurrentSurfaceRect(); + orientation = std::min(scene.GetCurrentSurfaceOrientation() / 90, 3); + } Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); - if( !eglImpl.IsPartialUpdateRequired() || mFullSwapNextFrame || !damagedRects.size() || (damagedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO) ) + if(!eglImpl.IsPartialUpdateRequired() || mFullSwapNextFrame || !damagedRects.size() || (damagedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO)) { mFullSwapNextFrame = false; - eglImpl.SwapBuffers( mEGLSurface ); + eglImpl.SwapBuffers(mEGLSurface); return; } mFullSwapNextFrame = false; - std::vector< Rect< int > > mergedRects = damagedRects; + std::vector> mergedRects = damagedRects; // Merge intersecting rects, form an array of non intersecting rects to help driver a bit // Could be optional and can be removed, needs to be checked with and without on platform const int n = mergedRects.size(); - for( int i = 0; i < n - 1; i++ ) + for(int i = 0; i < n - 1; i++) { - if( mergedRects[i].IsEmpty() ) + if(mergedRects[i].IsEmpty()) { continue; } - for( int j = i + 1; j < n; j++ ) + for(int j = i + 1; j < n; j++) { - if( mergedRects[j].IsEmpty() ) + if(mergedRects[j].IsEmpty()) { continue; } - if( mergedRects[i].Intersects( mergedRects[j] ) ) + if(mergedRects[i].Intersects(mergedRects[j])) { - mergedRects[i].Merge( mergedRects[j] ); - mergedRects[j].width = 0; + mergedRects[i].Merge(mergedRects[j]); + mergedRects[j].width = 0; mergedRects[j].height = 0; } } } int j = 0; - for( int i = 0; i < n; i++ ) + for(int i = 0; i < n; i++) { - if( !mergedRects[i].IsEmpty() ) + if(!mergedRects[i].IsEmpty()) { - mergedRects[j++] = mergedRects[i]; + mergedRects[j++] = RecalculateRect[orientation](mergedRects[i], surfaceRect); } } - if( j != 0 ) + if(j != 0) { - mergedRects.resize( j ); + mergedRects.resize(j); } - if( !mergedRects.size() || ( mergedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO ) ) + if(!mergedRects.size() || (mergedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO)) { - eglImpl.SwapBuffers( mEGLSurface ); + eglImpl.SwapBuffers(mEGLSurface); } else { - eglImpl.SwapBuffers( mEGLSurface, mergedRects ); + eglImpl.SwapBuffers(mEGLSurface, mergedRects); } } } } // namespace Adaptor -} // namespace internal +} // namespace Internal } // namespace Dali