X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fwindow-system%2Fcommon%2Fwindow-render-surface.cpp;h=a0523d309d020c2b96012c31b98453109b86c817;hb=c14e40e115165083feb961ddc43fc298bfe83859;hp=98afcfc55f3cf4d683ff46daa3c63d0ce768e354;hpb=935c0efc8a8f559eb3afad650e302219032fff24;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 98afcfc..a0523d3 100644 --- a/dali/internal/window-system/common/window-render-surface.cpp +++ b/dali/internal/window-system/common/window-render-surface.cpp @@ -79,6 +79,45 @@ void InsertRects(WindowRenderSurface::DamagedRectsContainer& damagedRectsList, c } } +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) @@ -88,7 +127,7 @@ WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any su mWindowBase(), mThreadSynchronization(nullptr), mRenderNotification(nullptr), - mRotationTrigger(nullptr), + mPostRenderTrigger(), mFrameRenderedTrigger(), mGraphics(nullptr), mEGLSurface(nullptr), @@ -106,7 +145,9 @@ WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any su mWindowRotationFinished(true), mScreenRotationFinished(true), mResizeFinished(true), - mDefaultScreenRotationAvailable(false) + mDefaultScreenRotationAvailable(false), + mIsImeWindowSurface(false), + mNeedWindowRotationAcknowledgement(false) { DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n"); Initialize(surface); @@ -114,10 +155,6 @@ WindowRenderSurface::WindowRenderSurface(Dali::PositionSize positionSize, Any su WindowRenderSurface::~WindowRenderSurface() { - if(mRotationTrigger) - { - delete mRotationTrigger; - } } void WindowRenderSurface::Initialize(Any surface) @@ -174,22 +211,23 @@ void WindowRenderSurface::SetTransparency(bool transparent) mWindowBase->SetTransparency(transparent); } -void WindowRenderSurface::RequestRotation(int angle, int width, int height) +void WindowRenderSurface::RequestRotation(int angle, PositionSize positionSize) { - 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; - mPositionSize.height = height; + mPositionSize = positionSize; mWindowRotationAngle = angle; mWindowRotationFinished = false; + mResizeFinished = false; mWindowBase->SetWindowRotationAngle(mWindowRotationAngle); - DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: angle = %d screen rotation = %d\n", mWindowRotationAngle, mScreenRotationAngle); + DALI_LOG_RELEASE_INFO("angle = %d screen rotation = %d, flag = %d\n", mWindowRotationAngle, mScreenRotationAngle, mWindowRotationFinished); } WindowBase* WindowRenderSurface::GetWindowBase() @@ -234,15 +272,15 @@ int WindowRenderSurface::GetOrientation() const void WindowRenderSurface::InitializeGraphics() { - mGraphics = &mAdaptor->GetGraphicsInterface(); + if(mEGLContext == NULL) + { + 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) - { // Create the OpenGL context for this window Internal::Adaptor::EglImplementation& eglImpl = static_cast(*mEGL); eglImpl.ChooseConfig(true, mColorDepth); @@ -277,8 +315,9 @@ void WindowRenderSurface::CreateSurface() Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); mEGLSurface = eglImpl.CreateSurfaceWindow(window, mColorDepth); - DALI_LOG_RELEASE_INFO("WindowRenderSurface::CreateSurface: WinId (%d), w = %d h = %d angle = %d screen rotation = %d\n", + DALI_LOG_RELEASE_INFO("WindowRenderSurface::CreateSurface: WinId (%d), EGLSurface (%p), w = %d h = %d angle = %d screen rotation = %d\n", mWindowBase->GetNativeWindowId(), + mEGLSurface, mPositionSize.width, mPositionSize.height, mWindowRotationAngle, @@ -338,6 +377,41 @@ bool WindowRenderSurface::ReplaceGraphicsSurface() return eglImpl.ReplaceSurfaceWindow(window, mEGLSurface, mEGLContext); } +void WindowRenderSurface::UpdatePositionSize(Dali::PositionSize positionSize) +{ + bool needToMove = false; + bool needToResize = false; + + // Check moving + if((fabs(positionSize.x - mPositionSize.x) >= MINIMUM_DIMENSION_CHANGE) || + (fabs(positionSize.y - mPositionSize.y) >= MINIMUM_DIMENSION_CHANGE)) + { + needToMove = true; + } + + // Check resizing + if((fabs(positionSize.width - mPositionSize.width) >= MINIMUM_DIMENSION_CHANGE) || + (fabs(positionSize.height - mPositionSize.height) >= MINIMUM_DIMENSION_CHANGE)) + { + needToResize = true; + } + + if(needToResize) + { + mResizeFinished = false; + mPositionSize = positionSize; + } + else + { + if(needToMove) + { + mPositionSize = positionSize; + } + } + + DALI_LOG_INFO(gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height); +} + void WindowRenderSurface::MoveResize(Dali::PositionSize positionSize) { bool needToMove = false; @@ -390,6 +464,10 @@ void WindowRenderSurface::StartRender() bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector>& damagedRects, Rect& clippingRect) { + InitializeGraphics(); + + mDamagedRects.assign(damagedRects.begin(), damagedRects.end()); + Dali::Integration::Scene::FrameCallbackContainer callbacks; Dali::Integration::Scene scene = mScene.GetHandle(); @@ -454,8 +532,6 @@ bool WindowRenderSurface::PreRender(bool resizingSurface, const std::vector PreRotation * wl_egl_window_tizen_set_buffer_transform(SetEglWindowBufferTransform) -> Screen Rotation @@ -465,7 +541,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, totalAngle: %d, x: %d, y: %d, w: %d, h:%d\n", totalAngle, positionSize.x, positionSize.y, positionSize.width, positionSize.height); } SetFullSwapNextFrame(); mDefaultScreenRotationAvailable = false; } - SetBufferDamagedRects(damagedRects, clippingRect); + SetBufferDamagedRects(mDamagedRects, clippingRect); + + if(scene) + { + Rect surfaceRect = scene.GetCurrentSurfaceRect(); + if(clippingRect == surfaceRect) + { + mDamagedRects.assign(1, surfaceRect); + } + else if(mDamagedRects.empty() && !clippingRect.IsEmpty()) + { + // We will render clippingRect area but mDamagedRects is empty. + // So make mDamagedRects same with clippingRect to swap buffers. + mDamagedRects.assign(1, clippingRect); + } + } + + // 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); @@ -526,37 +620,51 @@ void WindowRenderSurface::PostRender(bool renderToFbo, bool replacingSurface, bo GlImplementation& mGLES = eglGraphics->GetGlesInterface(); mGLES.PostRender(); - if(renderToFbo) - { - mGLES.Flush(); - mGLES.Finish(); - } - else + bool needWindowRotationCompleted = false; + + if(!mWindowRotationFinished) { - if(resizingSurface) + if(mNeedWindowRotationAcknowledgement) { - if(!mWindowRotationFinished) + Dali::Integration::Scene scene = mScene.GetHandle(); + if(scene) { - if(mThreadSynchronization) + if(scene.IsRotationCompletedAcknowledgementSet()) { - // Enable PostRender flag - mThreadSynchronization->PostRenderStarted(); + needWindowRotationCompleted = true; } + } + } + else + { + if(mIsResizing) + { + needWindowRotationCompleted = true; + } + } + } - DALI_LOG_RELEASE_INFO("WindowRenderSurface::PostRender: Trigger rotation event\n"); + if(needWindowRotationCompleted || mIsImeWindowSurface) + { + if(mThreadSynchronization) + { + // 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) { @@ -604,6 +712,21 @@ 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::SetNeedsRotationCompletedAcknowledgement(bool needAcknowledgement) +{ + mNeedWindowRotationAcknowledgement = needAcknowledgement; +} + void WindowRenderSurface::OutputTransformed() { int screenRotationAngle = mWindowBase->GetScreenRotationAngle(); @@ -624,13 +747,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) { @@ -695,28 +824,32 @@ void WindowRenderSurface::SetBufferDamagedRects(const std::vector>& da auto eglGraphics = static_cast(mGraphics); if(eglGraphics) { - Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); - if(!eglImpl.IsPartialUpdateRequired()) + // If scene is not exist, just use stored mPositionSize. + Rect surfaceRect(0, 0, mPositionSize.width, mPositionSize.height); + + Dali::Integration::Scene scene = mScene.GetHandle(); + if(scene) { - return; + surfaceRect = scene.GetCurrentSurfaceRect(); } - Rect surfaceRect(0, 0, mPositionSize.width, mPositionSize.height); - - if(mFullSwapNextFrame) + Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); + if(!eglImpl.IsPartialUpdateRequired() || mFullSwapNextFrame) { InsertRects(mBufferDamagedRects, std::vector>(1, surfaceRect)); - clippingRect = Rect(); + clippingRect = surfaceRect; return; } + mGraphics->ActivateSurfaceContext(this); + EGLint bufferAge = eglImpl.GetBufferAge(mEGLSurface); // Buffer age 0 means the back buffer in invalid and requires full swap - if(!damagedRects.size() || bufferAge == 0) + if(bufferAge == 0) { InsertRects(mBufferDamagedRects, std::vector>(1, surfaceRect)); - clippingRect = Rect(); + clippingRect = surfaceRect; return; } @@ -734,14 +867,24 @@ void WindowRenderSurface::SetBufferDamagedRects(const std::vector>& da if(!clippingRect.Intersect(surfaceRect) || clippingRect.Area() > surfaceRect.Area() * FULL_UPDATE_RATIO) { // clipping area too big or doesn't intersect surface rect - clippingRect = Rect(); + clippingRect = surfaceRect; return; } - std::vector> damagedRegion; - damagedRegion.push_back(clippingRect); + if(!clippingRect.IsEmpty()) + { + std::vector> damagedRegion; + 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); + } } } @@ -750,11 +893,19 @@ void WindowRenderSurface::SwapBuffers(const std::vector>& damagedRects auto eglGraphics = static_cast(mGraphics); if(eglGraphics) { - Rect 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() != 0 && damagedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO)) { mFullSwapNextFrame = false; eglImpl.SwapBuffers(mEGLSurface); @@ -796,7 +947,7 @@ void WindowRenderSurface::SwapBuffers(const std::vector>& damagedRects { if(!mergedRects[i].IsEmpty()) { - mergedRects[j++] = mergedRects[i]; + mergedRects[j++] = RecalculateRect[orientation](mergedRects[i], surfaceRect); } } @@ -807,6 +958,8 @@ void WindowRenderSurface::SwapBuffers(const std::vector>& damagedRects if(!mergedRects.size() || (mergedRects[0].Area() > surfaceRect.Area() * FULL_UPDATE_RATIO)) { + // In normal cases, WindowRenderSurface::SwapBuffers() will not be called if mergedRects.size() is 0. + // For exceptional cases, swap full area. eglImpl.SwapBuffers(mEGLSurface); } else