From: Anton Obzhirov Date: Tue, 14 Apr 2020 15:00:16 +0000 (+0100) Subject: Partial update implementation, first phase. X-Git-Tag: dali_1.5.17~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aa35ce5329eb4bc15b19d919f6ce7d0ceb64be7a;p=platform%2Fcore%2Fuifw%2Fdali-adaptor-legacy.git Partial update implementation, first phase. Change-Id: I222a1972d5727f6e01bb941b08339c38aad1546a --- diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.cpp b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.cpp index e8c0d12..b2a3fb9 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.cpp +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.cpp @@ -26,13 +26,15 @@ TestApplication::TestApplication( uint32_t surfaceWidth, uint32_t surfaceHeight, uint32_t horizontalDpi, uint32_t verticalDpi, - bool initialize ) + bool initialize, + bool enablePartialUpdate ) : mCore( NULL ), mSurfaceWidth( surfaceWidth ), mSurfaceHeight( surfaceHeight ), mFrame( 0u ), mDpi{ horizontalDpi, verticalDpi }, - mLastVSyncTime(0u) + mLastVSyncTime(0u), + mPartialUpdateEnabled(enablePartialUpdate) { if( initialize ) { @@ -59,7 +61,8 @@ void TestApplication::CreateCore() mGlContextHelperAbstraction, Integration::RenderToFrameBuffer::FALSE, Integration::DepthBufferAvailable::TRUE, - Integration::StencilBufferAvailable::TRUE ); + Integration::StencilBufferAvailable::TRUE, + mPartialUpdateEnabled ? Integration::PartialUpdateAvailable::TRUE : Integration::PartialUpdateAvailable::FALSE ); mCore->ContextCreated(); @@ -193,8 +196,8 @@ bool TestApplication::Render( uint32_t intervalMilliseconds, const char* locatio mRenderStatus.SetNeedsPostRender( false ); mCore->PreRender( mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/ ); - mCore->RenderScene( mRenderStatus, mScene, true /*render the off-screen buffers*/); - mCore->RenderScene( mRenderStatus, mScene, false /*render the surface*/); + mCore->RenderScene( mRenderStatus, mScene, true /*render the off-screen buffers*/ ); + mCore->RenderScene( mRenderStatus, mScene, false /*render the surface*/ ); mCore->PostRender( false /*do not skip rendering*/ ); mFrame++; @@ -202,6 +205,27 @@ bool TestApplication::Render( uint32_t intervalMilliseconds, const char* locatio return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate(); } +bool TestApplication::PreRenderWithPartialUpdate(uint32_t intervalMilliseconds, const char* location, std::vector>& damagedRects) +{ + DoUpdate(intervalMilliseconds, location); + + mCore->PreRender(mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/ ); + mCore->PreRender(mScene, damagedRects); + + return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate(); +} + +bool TestApplication::RenderWithPartialUpdate(std::vector>& damagedRects, Rect& clippingRect) +{ + mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/, clippingRect); + mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/, clippingRect); + mCore->PostRender(false /*do not skip rendering*/); + + mFrame++; + + return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate(); +} + uint32_t TestApplication::GetUpdateStatus() { return mStatus.KeepUpdating(); @@ -227,8 +251,8 @@ bool TestApplication::RenderOnly( ) { // Update Time values mCore->PreRender( mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/ ); - mCore->RenderScene( mRenderStatus, mScene, true /*render the off-screen buffers*/); - mCore->RenderScene( mRenderStatus, mScene, false /*render the surface*/); + mCore->RenderScene( mRenderStatus, mScene, true /*render the off-screen buffers*/ ); + mCore->RenderScene( mRenderStatus, mScene, false /*render the surface*/ ); mCore->PostRender( false /*do not skip rendering*/ ); mFrame++; diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.h index e96f759..1df0743 100644 --- a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.h +++ b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.h @@ -51,7 +51,8 @@ public: uint32_t surfaceHeight = DEFAULT_SURFACE_HEIGHT, uint32_t horizontalDpi = DEFAULT_HORIZONTAL_DPI, uint32_t verticalDpi = DEFAULT_VERTICAL_DPI, - bool initialize = true ); + bool initialize = true, + bool enablePartialUpdate = false ); void Initialize(); void CreateCore(); @@ -69,6 +70,8 @@ public: void ProcessEvent(const Integration::Event& event); void SendNotification(); bool Render( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL, const char* location=NULL ); + bool PreRenderWithPartialUpdate(uint32_t intervalMilliseconds, const char* location, std::vector>& damagedRects); + bool RenderWithPartialUpdate(std::vector>& damagedRects, Rect& clippingRect); uint32_t GetUpdateStatus(); bool UpdateOnly( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL ); bool RenderOnly( ); @@ -108,6 +111,7 @@ protected: struct { uint32_t x; uint32_t y; } mDpi; uint32_t mLastVSyncTime; + bool mPartialUpdateEnabled; static bool mLoggingEnabled; }; diff --git a/automated-tests/src/dali-adaptor/utc-Dali-Window.cpp b/automated-tests/src/dali-adaptor/utc-Dali-Window.cpp index 4b14df2..cb7de36 100644 --- a/automated-tests/src/dali-adaptor/utc-Dali-Window.cpp +++ b/automated-tests/src/dali-adaptor/utc-Dali-Window.cpp @@ -16,6 +16,7 @@ */ #include +#include #include #include @@ -412,3 +413,20 @@ int UtcDaliWindowFocusChangedSignalN(void) END_TEST; } + +int UtcDaliWindowPartialUpdate(void) +{ + Dali::Window window; + try + { + std::vector> damagedAreas; + DevelWindow::SetDamagedAreas(window, damagedAreas); + DALI_TEST_CHECK( false ); // Should not reach here! + } + catch( ... ) + { + DALI_TEST_CHECK( true ); + } + + END_TEST; +} diff --git a/dali/devel-api/adaptor-framework/window-devel.cpp b/dali/devel-api/adaptor-framework/window-devel.cpp index b9fadbb..44e9801 100755 --- a/dali/devel-api/adaptor-framework/window-devel.cpp +++ b/dali/devel-api/adaptor-framework/window-devel.cpp @@ -148,6 +148,11 @@ int32_t GetNativeId( Window window ) return GetImplementation( window ).GetNativeId(); } +void SetDamagedAreas(Window window, std::vector>& areas) +{ + GetImplementation(window).SetDamagedAreas(areas); +} + } // namespace DevelWindow } // namespace Dali diff --git a/dali/devel-api/adaptor-framework/window-devel.h b/dali/devel-api/adaptor-framework/window-devel.h index 958b940..1eb3501 100755 --- a/dali/devel-api/adaptor-framework/window-devel.h +++ b/dali/devel-api/adaptor-framework/window-devel.h @@ -2,7 +2,7 @@ #define DALI_WINDOW_DEVEL_H /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -18,7 +18,10 @@ * */ +// EXTERNAL INCLUDES + // INTERNAL INCLUDES +#include #include namespace Dali @@ -250,6 +253,16 @@ DALI_ADAPTOR_API void SetAvailableOrientations( Window window, const Dali::Vecto */ DALI_ADAPTOR_API int32_t GetNativeId( Window window ); +/** + * @brief Sets damaged areas of the window. + * + * This API is for setting static damaged areas of the window for partial update. + * + * @param[in] window The window instance + * @param[in] areas The damaged areas list to set + */ +DALI_ADAPTOR_API void SetDamagedAreas(Window window, std::vector>& areas); + } // namespace DevelWindow } // namespace Dali diff --git a/dali/integration-api/adaptor-framework/render-surface-interface.h b/dali/integration-api/adaptor-framework/render-surface-interface.h index 25ad128..e148662 100644 --- a/dali/integration-api/adaptor-framework/render-surface-interface.h +++ b/dali/integration-api/adaptor-framework/render-surface-interface.h @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include +#include #include #include #include @@ -136,9 +137,10 @@ public: * If the operation fails, then Core::Render should not be called until there is * a surface to render onto. * @param[in] resizingSurface True if the surface is being resized + * @param[in] damagedRects List of damaged rects this render pass * @return True if the operation is successful, False if the operation failed */ - virtual bool PreRender( bool resizingSurface ) = 0; + virtual bool PreRender( bool resizingSurface, const std::vector>& damagedRects, Rect& clippingRect ) = 0; /** * @brief Invoked by render thread after Core::Render @@ -146,7 +148,8 @@ public: * @param[in] replacingSurface True if the surface is being replaced. * @param[in] resizingSurface True if the surface is being resized. */ - virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ) = 0; + virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector>& damagedRects ) = 0; + /** * @brief Invoked by render thread when the thread should be stop */ diff --git a/dali/integration-api/adaptor-framework/scene-holder-impl.cpp b/dali/integration-api/adaptor-framework/scene-holder-impl.cpp index 7162a1c..5bbe94b 100644 --- a/dali/integration-api/adaptor-framework/scene-holder-impl.cpp +++ b/dali/integration-api/adaptor-framework/scene-holder-impl.cpp @@ -31,6 +31,7 @@ // INTERNAL INCLUDES #include #include +#include #include #include @@ -208,6 +209,13 @@ void SceneHolder::SurfaceResized() { PositionSize surfacePositionSize = mSurface->GetPositionSize(); mScene.SurfaceResized( static_cast( surfacePositionSize.width ), static_cast( surfacePositionSize.height ) ); + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } } Dali::RenderSurfaceInterface* SceneHolder::GetSurface() const @@ -220,6 +228,13 @@ void SceneHolder::SetBackgroundColor( const Vector4& color ) if( mScene ) { mScene.SetBackgroundColor( color ); + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } } } diff --git a/dali/internal/adaptor/common/adaptor-impl.cpp b/dali/internal/adaptor/common/adaptor-impl.cpp index a48eb5f..58f9c85 100755 --- a/dali/internal/adaptor/common/adaptor-impl.cpp +++ b/dali/internal/adaptor/common/adaptor-impl.cpp @@ -181,7 +181,8 @@ void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration: eglContextHelperImpl, ( 0u != mEnvironmentOptions->GetRenderToFboInterval() ) ? Integration::RenderToFrameBuffer::TRUE : Integration::RenderToFrameBuffer::FALSE, mGraphics->GetDepthBufferRequired(), - mGraphics->GetStencilBufferRequired() ); + mGraphics->GetStencilBufferRequired(), + mGraphics->GetPartialUpdateRequired() ); defaultWindow->SetAdaptor( Get() ); diff --git a/dali/internal/adaptor/common/combined-update-render-controller.cpp b/dali/internal/adaptor/common/combined-update-render-controller.cpp index b310671..b514cb6 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.cpp +++ b/dali/internal/adaptor/common/combined-update-render-controller.cpp @@ -745,18 +745,35 @@ void CombinedUpdateRenderController::UpdateRenderThread() windowSurface->InitializeGraphics(); + // clear previous frame damaged render items rects, buffer history is tracked on surface level + mDamagedRects.clear(); + + // If user damaged areas are not set + if (!eglImpl.DamageAreasSet()) + { + // Collect damage rects + mCore.PreRender( scene, mDamagedRects ); + } + // Render off-screen frame buffers first if any mCore.RenderScene( windowRenderStatus, scene, true ); - // Switch to the EGL context of the surface - windowSurface->PreRender( surfaceResized ); // Switch GL context + Rect clippingRect; // Empty for fbo rendering + + // Switch to the EGL context of the surface, merge damaged areas for previous frames + windowSurface->PreRender( surfaceResized, mDamagedRects, clippingRect ); // Switch GL context + + if (clippingRect.IsEmpty()) + { + mDamagedRects.clear(); + } // Render the surface - mCore.RenderScene( windowRenderStatus, scene, false ); + mCore.RenderScene( windowRenderStatus, scene, false, clippingRect ); if( windowRenderStatus.NeedsPostRender() ) { - windowSurface->PostRender( false, false, surfaceResized ); // Swap Buffer + windowSurface->PostRender( false, false, surfaceResized, mDamagedRects ); // Swap Buffer with damage } } } diff --git a/dali/internal/adaptor/common/combined-update-render-controller.h b/dali/internal/adaptor/common/combined-update-render-controller.h index 965479e..8dfd4eb 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.h +++ b/dali/internal/adaptor/common/combined-update-render-controller.h @@ -391,6 +391,8 @@ private: volatile unsigned int mUploadWithoutRendering; ///< Will be set to upload the resource only (with no rendering) volatile unsigned int mFirstFrameAfterResume; ///< Will be set to check the first frame after resume (for log) + + std::vector> mDamagedRects; ///< Keeps collected damaged render items rects for one render pass }; } // namespace Adaptor diff --git a/dali/internal/graphics/common/graphics-interface.h b/dali/internal/graphics/common/graphics-interface.h index 93c1b2f..4404fab 100644 --- a/dali/internal/graphics/common/graphics-interface.h +++ b/dali/internal/graphics/common/graphics-interface.h @@ -42,8 +42,9 @@ public: * Constructor */ GraphicsInterface() -: mDepthBufferRequired( Integration::DepthBufferAvailable::FALSE ), - mStencilBufferRequired( Integration::StencilBufferAvailable::FALSE ) + : mDepthBufferRequired( Integration::DepthBufferAvailable::FALSE ), + mStencilBufferRequired( Integration::StencilBufferAvailable::FALSE ), + mPartialUpdateRequired( Integration::PartialUpdateAvailable::FALSE ) { }; @@ -81,11 +82,20 @@ public: return mStencilBufferRequired; }; + /** + * Get whether the stencil buffer is required + * @return TRUE if the stencil buffer is required + */ + Integration::PartialUpdateAvailable GetPartialUpdateRequired() + { + return mPartialUpdateRequired; + }; protected: Integration::DepthBufferAvailable mDepthBufferRequired; ///< Whether the depth buffer is required Integration::StencilBufferAvailable mStencilBufferRequired; ///< Whether the stencil buffer is required + Integration::PartialUpdateAvailable mPartialUpdateRequired; ///< Whether the partial update is required }; } // Adaptor diff --git a/dali/internal/graphics/gles/egl-graphics.cpp b/dali/internal/graphics/gles/egl-graphics.cpp index 406e69c..e13ce0b 100644 --- a/dali/internal/graphics/gles/egl-graphics.cpp +++ b/dali/internal/graphics/gles/egl-graphics.cpp @@ -62,6 +62,7 @@ void EglGraphics::Initialize( EnvironmentOptions* environmentOptions ) mDepthBufferRequired = static_cast< Integration::DepthBufferAvailable >( environmentOptions->DepthBufferRequired() ); mStencilBufferRequired = static_cast< Integration::StencilBufferAvailable >( environmentOptions->StencilBufferRequired() ); + mPartialUpdateRequired = static_cast< Integration::PartialUpdateAvailable >( environmentOptions->PartialUpdateRequired() ); mMultiSamplingLevel = environmentOptions->GetMultiSamplingLevel(); @@ -72,7 +73,7 @@ void EglGraphics::Initialize( EnvironmentOptions* environmentOptions ) EglInterface* EglGraphics::Create() { - mEglImplementation = Utils::MakeUnique< EglImplementation >( mMultiSamplingLevel, mDepthBufferRequired, mStencilBufferRequired ); + mEglImplementation = Utils::MakeUnique< EglImplementation >( mMultiSamplingLevel, mDepthBufferRequired, mStencilBufferRequired, mPartialUpdateRequired ); mEglImageExtensions = Utils::MakeUnique< EglImageExtensions >( mEglImplementation.get() ); mEglSync->Initialize( mEglImplementation.get() ); // The sync impl needs the EglDisplay @@ -128,6 +129,16 @@ EglImageExtensions* EglGraphics::GetImageExtensions() return mEglImageExtensions.get(); } +void EglGraphics::SetDamagedAreas(std::vector>& areas) +{ + mEglImplementation->SetDamageAreas(areas); +} + +void EglGraphics::SetFullSwapNextFrame() +{ + mEglImplementation->SetFullSwapNextFrame(); +} + } // Adaptor } // Internal } // Dali diff --git a/dali/internal/graphics/gles/egl-graphics.h b/dali/internal/graphics/gles/egl-graphics.h index 8ee45bc..410395c 100644 --- a/dali/internal/graphics/gles/egl-graphics.h +++ b/dali/internal/graphics/gles/egl-graphics.h @@ -126,6 +126,16 @@ public: EglImageExtensions* GetImageExtensions(); /** + * Sets fixed damaged areas for partial rendering. This overrides automatic partial rendering. + */ + void SetDamagedAreas( std::vector>& areas ); + + /** + * Instructs egl implementation to do full swap regardless of stored data, resets the data. + */ + void SetFullSwapNextFrame(); + + /** * @copydoc Dali::Internal::Adaptor::GraphicsInterface::Destroy() */ void Destroy() override; diff --git a/dali/internal/graphics/gles/egl-implementation.cpp b/dali/internal/graphics/gles/egl-implementation.cpp index 38851f9..3710dd1 100755 --- a/dali/internal/graphics/gles/egl-implementation.cpp +++ b/dali/internal/graphics/gles/egl-implementation.cpp @@ -63,7 +63,8 @@ namespace Adaptor EglImplementation::EglImplementation( int multiSamplingLevel, Integration::DepthBufferAvailable depthBufferRequired, - Integration::StencilBufferAvailable stencilBufferRequired ) + Integration::StencilBufferAvailable stencilBufferRequired , + Integration::PartialUpdateAvailable partialUpdateRequired ) : mContextAttribs(), mEglNativeDisplay( 0 ), mEglNativeWindow( 0 ), @@ -81,9 +82,14 @@ EglImplementation::EglImplementation( int multiSamplingLevel, mIsWindow( true ), mDepthBufferRequired( depthBufferRequired == Integration::DepthBufferAvailable::TRUE ), mStencilBufferRequired( stencilBufferRequired == Integration::StencilBufferAvailable::TRUE ), + mPartialUpdateRequired( partialUpdateRequired == Integration::PartialUpdateAvailable::TRUE ), mIsSurfacelessContextSupported( false ), mIsKhrCreateContextSupported( false ), - mSwapBufferCountAfterResume( 0 ) + mSwapBufferCountAfterResume( 0 ), + mEglSetDamageRegionKHR( 0 ), + mEglSwapBuffersWithDamageKHR( 0 ), + mBufferAge( 0 ), + mFullSwapNextFrame( true ) { } @@ -169,6 +175,18 @@ bool EglImplementation::CreateContext() DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** GL_SHADING_LANGUAGE_VERSION : %s***\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", glGetString(GL_EXTENSIONS)); + mEglSetDamageRegionKHR = reinterpret_cast(eglGetProcAddress("eglSetDamageRegionKHR")); + if (!mEglSetDamageRegionKHR) + { + DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n"); + mPartialUpdateRequired = false; + } + mEglSwapBuffersWithDamageKHR = reinterpret_cast(eglGetProcAddress("eglSwapBuffersWithDamageKHR")); + if (!mEglSwapBuffersWithDamageKHR) + { + DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n"); + mPartialUpdateRequired = false; + } return true; } @@ -190,6 +208,18 @@ bool EglImplementation::CreateWindowContext( EGLContext& eglContext ) mEglWindowContexts.push_back( eglContext ); + mEglSetDamageRegionKHR = reinterpret_cast(eglGetProcAddress("eglSetDamageRegionKHR")); + if (!mEglSetDamageRegionKHR) + { + DALI_LOG_ERROR("Coudn't find eglSetDamageRegionKHR!\n"); + mPartialUpdateRequired = false; + } + mEglSwapBuffersWithDamageKHR = reinterpret_cast(eglGetProcAddress("eglSwapBuffersWithDamageKHR")); + if (!mEglSwapBuffersWithDamageKHR) + { + DALI_LOG_ERROR("Coudn't find eglSwapBuffersWithDamageKHR!\n"); + mPartialUpdateRequired = false; + } return true; } @@ -321,7 +351,266 @@ void EglImplementation::SwapBuffers( EGLSurface& eglSurface ) } #endif //DALI_PROFILE_UBUNTU + // DALI_LOG_ERROR("EglImplementation::SwapBuffers()\n"); eglSwapBuffers( mEglDisplay, eglSurface ); + mFullSwapNextFrame = false; + +#ifndef DALI_PROFILE_UBUNTU + if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT ) + { + DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" ); + mSwapBufferCountAfterResume++; + } +#endif //DALI_PROFILE_UBUNTU + } +} + +EGLint EglImplementation::GetBufferAge(EGLSurface& eglSurface) const +{ + EGLint age = 0; + eglQuerySurface(mEglDisplay, eglSurface, EGL_BUFFER_AGE_EXT, &age); + if (age < 0) + { + DALI_LOG_ERROR("eglQuerySurface(%d)\n", eglGetError()); + age = 0; + } + + // 0 - invalid buffer + // 1, 2, 3 + if (age > 3) + { + DALI_LOG_ERROR("EglImplementation::GetBufferAge() buffer age %d > 3\n", age); + age = 0; // shoudn't be more than 3 back buffers, if there is just reset, I don't want to add extra history level + } + + return age; +} + +bool EglImplementation::DamageAreasSet() const +{ + return (mDamagedAreas.size() ? true : false); +} + +void EglImplementation::SetDamageAreas( std::vector>& damagedAreas ) +{ + mFullSwapNextFrame = true; + mDamagedAreas = damagedAreas; +} + +void EglImplementation::SetFullSwapNextFrame() +{ + mFullSwapNextFrame = true; +} + +void mergeRects(Rect& mergingRect, const std::vector>& rects) +{ + uint32_t i = 0; + if (mergingRect.IsEmpty()) + { + for (;i < rects.size(); i++) + { + if (!rects[i].IsEmpty()) + { + mergingRect = rects[i]; + break; + } + } + } + + for (;i < rects.size(); i++) + { + mergingRect.Merge(rects[i]); + } +} + +void insertRects(std::list>>& damagedRectsList, const std::vector>& damagedRects) +{ + damagedRectsList.push_front(damagedRects); + if (damagedRectsList.size() > 4) // past triple buffers + current + { + damagedRectsList.pop_back(); + } +} + +void EglImplementation::SetDamage( EGLSurface& eglSurface, const std::vector>& damagedRects, Rect& clippingRect ) +{ + if (!mPartialUpdateRequired) + { + return; + } + + if (eglSurface != EGL_NO_SURFACE) // skip if using surfaceless context + { + EGLint width = 0; + EGLint height = 0; + eglQuerySurface(mEglDisplay, eglSurface, EGL_WIDTH, &width); + eglQuerySurface(mEglDisplay, eglSurface, EGL_HEIGHT, &height); + Rect surfaceRect(0, 0, width, height); + + mSurfaceRect = surfaceRect; + + if (mFullSwapNextFrame) + { + mBufferAge = 0; + insertRects(mBufferDamagedRects, std::vector>(1, surfaceRect)); + clippingRect = Rect(); + return; + } + + EGLint bufferAge = GetBufferAge(eglSurface); + if (mDamagedAreas.size()) + { + mBufferAge = bufferAge; + if (bufferAge == 0) + { + // Buffer age is reset + clippingRect = Rect(); + return; + } + + mergeRects(clippingRect, mDamagedAreas); + } + else + { + // Buffer age 0 means the back buffer in invalid and requires full swap + if (!damagedRects.size() || bufferAge != mBufferAge || bufferAge == 0) + { + // No damage or buffer is out of order or buffer age is reset + mBufferAge = bufferAge; + insertRects(mBufferDamagedRects, std::vector>(1, surfaceRect)); + clippingRect = Rect(); + return; + } + + // We push current frame damaged rects here, zero index for current frame + mBufferAge = bufferAge; + insertRects(mBufferDamagedRects, damagedRects); + + // Merge damaged rects into clipping rect + auto bufferDamagedRects = mBufferDamagedRects.begin(); + while (bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end()) + { + const std::vector>& rects = *bufferDamagedRects++; + mergeRects(clippingRect, rects); + } + } + + if (!clippingRect.Intersect(surfaceRect) || clippingRect.Area() > surfaceRect.Area() * 0.8) + { + // clipping area too big or doesn't intersect surface rect + clippingRect = Rect(); + return; + } + + // DALI_LOG_ERROR("eglSetDamageRegionKHR(%d, %d, %d, %d)\n", clippingRect.x, clippingRect.y, clippingRect.width, clippingRect.height); + EGLBoolean result = mEglSetDamageRegionKHR(mEglDisplay, eglSurface, reinterpret_cast(&clippingRect), 1); + if (result == EGL_FALSE) + { + DALI_LOG_ERROR("eglSetDamageRegionKHR(%d)\n", eglGetError()); + } + } +} + +void EglImplementation::SwapBuffers(EGLSurface& eglSurface, const std::vector>& damagedRects) +{ + if (eglSurface != EGL_NO_SURFACE ) // skip if using surfaceless context + { + if (!mPartialUpdateRequired || mFullSwapNextFrame || mBufferAge == 0 || !damagedRects.size()) + { + SwapBuffers(eglSurface); + return; + } + +#ifndef DALI_PROFILE_UBUNTU + if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT ) + { + DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers started.\n" ); + } +#endif //DALI_PROFILE_UBUNTU + + if (mDamagedAreas.size()) + { + // DALI_LOG_ERROR("EglImplementation::SwapBuffers(%d)\n", mDamagedAreas.size()); + EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast(mDamagedAreas.data()), mDamagedAreas.size()); + if (result == EGL_FALSE) + { + DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError()); + } + +#ifndef DALI_PROFILE_UBUNTU + if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT ) + { + DALI_LOG_RELEASE_INFO( "EglImplementation::SwapBuffers finished.\n" ); + mSwapBufferCountAfterResume++; + } +#endif //DALI_PROFILE_UBUNTU + return; + } + + // current frame damaged rects were pushed by EglImplementation::SetDamage() to 0 index. + EGLint bufferAge = mBufferAge; + mCombinedDamagedRects.clear(); + + // Combine damaged rects from previous frames (beginning from bufferAge index) with the current frame (0 index) + auto bufferDamagedRects = mBufferDamagedRects.begin(); + while (bufferAge-- >= 0 && bufferDamagedRects != mBufferDamagedRects.end()) + { + const std::vector>& rects = *bufferDamagedRects++; + mCombinedDamagedRects.insert(mCombinedDamagedRects.end(), rects.begin(), rects.end()); + } + + // 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 = mCombinedDamagedRects.size(); + for (int i = 0; i < n-1; i++) + { + if (mCombinedDamagedRects[i].IsEmpty()) + { + continue; + } + + for (int j = i+1; j < n; j++) + { + if (mCombinedDamagedRects[j].IsEmpty()) + { + continue; + } + + if (mCombinedDamagedRects[i].Intersects(mCombinedDamagedRects[j])) + { + mCombinedDamagedRects[i].Merge(mCombinedDamagedRects[j]); + mCombinedDamagedRects[j].width = 0; + mCombinedDamagedRects[j].height = 0; + } + } + } + + int j = 0; + for (int i = 0; i < n; i++) + { + if (!mCombinedDamagedRects[i].IsEmpty()) + { + mCombinedDamagedRects[j++] = mCombinedDamagedRects[i]; + } + } + + if (j != 0) + { + mCombinedDamagedRects.resize(j); + } + + if (!mCombinedDamagedRects.size() || (mCombinedDamagedRects[0].Area() > mSurfaceRect.Area() * 0.8)) + { + SwapBuffers(eglSurface); + return; + } + + // DALI_LOG_ERROR("EglImplementation::SwapBuffers(%d)\n", mCombinedDamagedRects.size()); + EGLBoolean result = mEglSwapBuffersWithDamageKHR(mEglDisplay, eglSurface, reinterpret_cast(mCombinedDamagedRects.data()), mCombinedDamagedRects.size()); + if (result == EGL_FALSE) + { + DALI_LOG_ERROR("eglSwapBuffersWithDamageKHR(%d)\n", eglGetError()); + } #ifndef DALI_PROFILE_UBUNTU if( mSwapBufferCountAfterResume < THRESHOLD_SWAPBUFFER_COUNT ) diff --git a/dali/internal/graphics/gles/egl-implementation.h b/dali/internal/graphics/gles/egl-implementation.h index efb9754..b505352 100644 --- a/dali/internal/graphics/gles/egl-implementation.h +++ b/dali/internal/graphics/gles/egl-implementation.h @@ -19,9 +19,13 @@ */ // EXTERNAL INCLUDES +#include +#include + #include #include #include +#include #include // INTERNAL INCLUDES @@ -46,10 +50,12 @@ public: * @param[in] multiSamplingLevel The Multi-sampling level required * @param[in] depthBufferRequired Whether the depth buffer is required * @param[in] stencilBufferRequired Whether the stencil buffer is required + * @param[in] partialUpdatedRequired Whether the partial update is required */ EglImplementation( int multiSamplingLevel, Integration::DepthBufferAvailable depthBufferRequired, - Integration::StencilBufferAvailable stencilBufferRequired ); + Integration::StencilBufferAvailable stencilBufferRequired, + Integration::PartialUpdateAvailable partialUpdateRequired ); /** * Destructor @@ -124,6 +130,36 @@ public: virtual void SwapBuffers( EGLSurface& eglSurface ); /** + * Gets current back buffer age + */ + EGLint GetBufferAge( EGLSurface& eglSurface ) const; + + /** + * Gets if user set damaged areas + */ + bool DamageAreasSet() const; + + /** + * Sets damaged areas, overrides auto calculated ones + */ + void SetDamageAreas( std::vector>& damagedArea ); + + /** + * Forces full surface swap next frame, resets current partial update state. + */ + void SetFullSwapNextFrame(); + + /** + * Performs an OpenGL set damage command with damaged rects + */ + virtual void SetDamage( EGLSurface& eglSurface, const std::vector>& damagedRects, Rect& clippingRect ); + + /** + * Performs an OpenGL swap buffers command with damaged rects + */ + virtual void SwapBuffers( EGLSurface& eglSurface, const std::vector>& damagedRects ); + + /** * Performs an OpenGL copy buffers command */ virtual void CopyBuffers( EGLSurface& eglSurface ); @@ -246,10 +282,20 @@ private: bool mIsWindow; bool mDepthBufferRequired; bool mStencilBufferRequired; + bool mPartialUpdateRequired; bool mIsSurfacelessContextSupported; bool mIsKhrCreateContextSupported; uint32_t mSwapBufferCountAfterResume; + PFNEGLSETDAMAGEREGIONKHRPROC mEglSetDamageRegionKHR; + PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC mEglSwapBuffersWithDamageKHR; + + EGLint mBufferAge; + std::list>> mBufferDamagedRects; + std::vector> mCombinedDamagedRects; + std::vector> mDamagedAreas; + Rect mSurfaceRect; + bool mFullSwapNextFrame; }; } // namespace Adaptor diff --git a/dali/internal/system/common/environment-options.cpp b/dali/internal/system/common/environment-options.cpp index 7fea428..1d00be7 100644 --- a/dali/internal/system/common/environment-options.cpp +++ b/dali/internal/system/common/environment-options.cpp @@ -42,6 +42,7 @@ const unsigned int DEFAULT_STATISTICS_LOG_FREQUENCY = 2; const int DEFAULT_MULTI_SAMPLING_LEVEL = -1; const bool DEFAULT_DEPTH_BUFFER_REQUIRED_SETTING = true; const bool DEFAULT_STENCIL_BUFFER_REQUIRED_SETTING = true; +const bool DEFAULT_PARTIAL_UPDATE_REQUIRED_SETTING = false; unsigned int GetIntegerEnvironmentVariable( const char* variable, unsigned int defaultValue ) { @@ -130,7 +131,8 @@ EnvironmentOptions::EnvironmentOptions() mThreadingMode( ThreadingMode::COMBINED_UPDATE_RENDER ), mGlesCallAccumulate( false ), mDepthBufferRequired( DEFAULT_DEPTH_BUFFER_REQUIRED_SETTING ), - mStencilBufferRequired( DEFAULT_STENCIL_BUFFER_REQUIRED_SETTING ) + mStencilBufferRequired( DEFAULT_STENCIL_BUFFER_REQUIRED_SETTING ), + mPartialUpdateRequired( DEFAULT_PARTIAL_UPDATE_REQUIRED_SETTING ) { ParseEnvironmentOptions(); } @@ -391,6 +393,11 @@ bool EnvironmentOptions::StencilBufferRequired() const return mStencilBufferRequired; } +bool EnvironmentOptions::PartialUpdateRequired() const +{ + return mPartialUpdateRequired; +} + void EnvironmentOptions::ParseEnvironmentOptions() { // get logging options @@ -660,6 +667,15 @@ void EnvironmentOptions::ParseEnvironmentOptions() mStencilBufferRequired = false; } } + + int partialUpdateRequired( -1 ); + if( GetIntegerEnvironmentVariable( DALI_ENV_ENABLE_PARTIAL_UPDATE, partialUpdateRequired ) ) + { + if( partialUpdateRequired > 0 ) + { + mPartialUpdateRequired = true; + } + } } } // Adaptor diff --git a/dali/internal/system/common/environment-options.h b/dali/internal/system/common/environment-options.h index f72ebdd..4d4b458 100644 --- a/dali/internal/system/common/environment-options.h +++ b/dali/internal/system/common/environment-options.h @@ -316,6 +316,11 @@ public: */ bool StencilBufferRequired() const; + /** + * @return Whether the partial update is required. + */ + bool PartialUpdateRequired() const; + /// Deleted copy constructor. EnvironmentOptions( const EnvironmentOptions& ) = delete; @@ -383,6 +388,7 @@ private: // Data bool mGlesCallAccumulate; ///< Whether or not to accumulate gles call statistics bool mDepthBufferRequired; ///< Whether the depth buffer is required bool mStencilBufferRequired; ///< Whether the stencil buffer is required + bool mPartialUpdateRequired; ///< Whether the partial update is required std::unique_ptr mTraceManager; ///< TraceManager }; diff --git a/dali/internal/system/common/environment-variables.h b/dali/internal/system/common/environment-variables.h index ca1a9c8..1be9185 100644 --- a/dali/internal/system/common/environment-variables.h +++ b/dali/internal/system/common/environment-variables.h @@ -128,6 +128,8 @@ namespace Adaptor #define DALI_ENV_DISABLE_STENCIL_BUFFER "DALI_DISABLE_STENCIL_BUFFER" +#define DALI_ENV_ENABLE_PARTIAL_UPDATE "DALI_ENABLE_PARTIAL_UPDATE" + #define DALI_ENV_WEB_ENGINE_NAME "DALI_WEB_ENGINE_NAME" #define DALI_ENV_DPI_HORIZONTAL "DALI_DPI_HORIZONTAL" diff --git a/dali/internal/window-system/common/window-impl.cpp b/dali/internal/window-system/common/window-impl.cpp index b21ca77..15be716 100755 --- a/dali/internal/window-system/common/window-impl.cpp +++ b/dali/internal/window-system/common/window-impl.cpp @@ -32,6 +32,7 @@ // INTERNAL HEADERS #include +#include #include #include #include @@ -188,18 +189,42 @@ std::string Window::GetClassName() const void Window::Raise() { mWindowBase->Raise(); + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } + DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Raise() \n", this, mNativeWindowId ); } void Window::Lower() { mWindowBase->Lower(); + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } + DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Lower() \n", this, mNativeWindowId ); } void Window::Activate() { mWindowBase->Activate(); + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } + DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Activate() \n", this, mNativeWindowId ); } @@ -412,6 +437,13 @@ void Window::Show() mVisibilityChangedSignal.Emit( handle, true ); } + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } + DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Show(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible ); } @@ -430,6 +462,14 @@ void Window::Hide() mVisibilityChangedSignal.Emit( handle, false ); } + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } + DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Hide(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible ); } @@ -478,6 +518,13 @@ void Window::SetInputRegion( const Rect< int >& inputRegion ) { mWindowBase->SetInputRegion( inputRegion ); + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } + DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetInputRegion: x = %d, y = %d, w = %d, h = %d\n", inputRegion.x, inputRegion.y, inputRegion.width, inputRegion.height ); } @@ -589,6 +636,13 @@ void Window::SetSize( Dali::Window::WindowSize size ) mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize ); } + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } } Dali::Window::WindowSize Window::GetSize() const @@ -609,6 +663,13 @@ void Window::SetPosition( Dali::Window::WindowPosition position ) PositionSize oldRect = mSurface->GetPositionSize(); mWindowSurface->MoveResize( PositionSize( position.GetX(), position.GetY(), oldRect.width, oldRect.height ) ); + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } } Dali::Window::WindowPosition Window::GetPosition() const @@ -647,6 +708,13 @@ void Window::SetPositionSize( PositionSize positionSize ) mResizeSignal.Emit( handle, newSize ); mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize ); } + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } } Dali::Layer Window::GetRootLayer() const @@ -711,6 +779,13 @@ void Window::OnIconifyChanged( bool iconified ) DALI_LOG_RELEASE_INFO( "Window (%p), WinId (%d), Deiconified: visible = %d\n", this, mNativeWindowId, mVisible ); } + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } } void Window::OnFocusChanged( bool focusIn ) @@ -718,6 +793,13 @@ void Window::OnFocusChanged( bool focusIn ) Dali::Window handle( this ); mFocusChangedSignal.Emit( focusIn ); mFocusChangeSignal.Emit( handle, focusIn ); + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } } void Window::OnOutputTransformed() @@ -784,6 +866,13 @@ void Window::OnPause() { mEventHandler->Pause(); } + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } } void Window::OnResume() @@ -792,6 +881,13 @@ void Window::OnResume() { mEventHandler->Resume(); } + + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetFullSwapNextFrame(); + } } void Window::RecalculateTouchPosition( Integration::Point& point ) @@ -915,6 +1011,16 @@ int32_t Window::GetNativeId() const return mWindowBase->GetNativeWindowId(); } +void Window::SetDamagedAreas(std::vector>& areas) +{ + GraphicsInterface& graphics = mAdaptor->GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + if (eglGraphics) + { + eglGraphics->SetDamagedAreas(areas); + } +} + } // Adaptor } // Internal diff --git a/dali/internal/window-system/common/window-impl.h b/dali/internal/window-system/common/window-impl.h index ca1d3bf..3a877ae 100755 --- a/dali/internal/window-system/common/window-impl.h +++ b/dali/internal/window-system/common/window-impl.h @@ -359,6 +359,11 @@ public: */ void SetAvailableOrientations( const Dali::Vector& orientations ); + /** + * @copydoc Dali::DevelWindow::SetDamagedAreas() + */ + void SetDamagedAreas(std::vector>& areas); + public: // Dali::Internal::Adaptor::SceneHolder /** diff --git a/dali/internal/window-system/common/window-render-surface.cpp b/dali/internal/window-system/common/window-render-surface.cpp index c95d508..dfaefa4 100644 --- a/dali/internal/window-system/common/window-render-surface.cpp +++ b/dali/internal/window-system/common/window-render-surface.cpp @@ -352,10 +352,12 @@ void WindowRenderSurface::StartRender() { } -bool WindowRenderSurface::PreRender( bool resizingSurface ) +bool WindowRenderSurface::PreRender( bool resizingSurface, const std::vector>& damagedRects, Rect& clippingRect ) { MakeContextCurrent(); + auto eglGraphics = static_cast(mGraphics); + if( resizingSurface ) { // Window rotate or screen rotate @@ -386,19 +388,24 @@ bool WindowRenderSurface::PreRender( bool resizingSurface ) 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); @@ -438,7 +445,7 @@ void WindowRenderSurface::PostRender( bool renderToFbo, bool replacingSurface, b } Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); - eglImpl.SwapBuffers( mEGLSurface ); + eglImpl.SwapBuffers( mEGLSurface, damagedRects ); if( mRenderNotification ) { diff --git a/dali/internal/window-system/common/window-render-surface.h b/dali/internal/window-system/common/window-render-surface.h index f8160b8..bc03611 100644 --- a/dali/internal/window-system/common/window-render-surface.h +++ b/dali/internal/window-system/common/window-render-surface.h @@ -156,12 +156,12 @@ public: // from Dali::RenderSurfaceInterface /** * @copydoc Dali::RenderSurfaceInterface::PreRender() */ - virtual bool PreRender( bool resizingSurface ) override; + virtual bool PreRender( bool resizingSurface, const std::vector>& damagedRects, Rect& clippingRect ) override; /** * @copydoc Dali::RenderSurfaceInterface::PostRender() */ - virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ); + virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector>& damagedRects ) override; /** * @copydoc Dali::RenderSurfaceInterface::StopRender() diff --git a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp index 3ef4f68..48069c7 100644 --- a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp @@ -216,20 +216,30 @@ void NativeRenderSurfaceEcoreWl::StartRender() { } -bool NativeRenderSurfaceEcoreWl::PreRender( bool ) +bool NativeRenderSurfaceEcoreWl::PreRender( bool resizingSurface, const std::vector>& damagedRects, Rect& clippingRect ) { - // nothing to do for pixmaps + auto eglGraphics = static_cast(mGraphics); + if (eglGraphics) + { + Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); + if (resizingSurface) + { + eglImpl.SetFullSwapNextFrame(); + } + + eglImpl.SetDamage(mEGLSurface, damagedRects, clippingRect); + } + return true; } -void NativeRenderSurfaceEcoreWl::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ) +void NativeRenderSurfaceEcoreWl::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector>& damagedRects ) { auto eglGraphics = static_cast(mGraphics); - if ( eglGraphics ) + if (eglGraphics) { Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); - - eglImpl.SwapBuffers( mEGLSurface ); + eglImpl.SwapBuffers( mEGLSurface, damagedRects ); } if( mThreadSynchronization ) diff --git a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h index e3a33ba..bfca63c 100644 --- a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h +++ b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h @@ -116,12 +116,12 @@ public: // from Dali::RenderSurfaceInterface /** * @copydoc Dali::RenderSurfaceInterface::PreRender() */ - virtual bool PreRender( bool resizingSurface ) override; + virtual bool PreRender( bool resizingSurface, const std::vector>& damagedRects, Rect& clippingRect ) override; /** * @copydoc Dali::RenderSurfaceInterface::PostRender() */ - virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ); + virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector>& damagedRects ) override; /** * @copydoc Dali::RenderSurfaceInterface::StopRender() diff --git a/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.cpp b/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.cpp index 2e93140..527f5cc 100644 --- a/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.cpp +++ b/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.cpp @@ -220,13 +220,13 @@ void PixmapRenderSurfaceEcoreX::StartRender() { } -bool PixmapRenderSurfaceEcoreX::PreRender( bool ) +bool PixmapRenderSurfaceEcoreX::PreRender( bool, const std::vector>&, Rect& ) { // Nothing to do for pixmaps return true; } -void PixmapRenderSurfaceEcoreX::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ) +void PixmapRenderSurfaceEcoreX::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector>& damagedRects ) { auto eglGraphics = static_cast(mGraphics); diff --git a/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.h b/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.h index 034fee6..ebedfef 100644 --- a/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.h +++ b/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.h @@ -114,12 +114,12 @@ public: // from Dali::RenderSurfaceInterface /** * @copydoc Dali::RenderSurfaceInterface::PreRender() */ - virtual bool PreRender( bool resizingSurface ) override; + virtual bool PreRender( bool resizingSurface, const std::vector>& damagedRects, Rect& clippingRect ) override; /** * @copydoc Dali::RenderSurfaceInterface::PostRender() */ - virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ) override; + virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface, const std::vector>& damagedRects ) override; /** * @copydoc Dali::RenderSurfaceInterface::StopRender()