From c398715c18cdaf20493e6aded77b30e22ed6b0d3 Mon Sep 17 00:00:00 2001 From: Wonsik Jung Date: Tue, 2 Jun 2020 11:09:23 +0900 Subject: [PATCH 01/16] Update window's geometry to ecore_wl2. When the ecore wl2 window is resized or changed position then the window is hidden, the window's position and size is not updated by the Tizen Display Server. Because wayland protocol is destroyed by window's hidden. To fix that, window's geometry is updated again before window is shown. Change-Id: Iafa6a7ae5509c54f2e11bd6bd3ca8e0d23a1439b --- .../tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp | 15 +++++++++++++++ .../tizen-wayland/ecore-wl2/window-base-ecore-wl2.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp index 89fae58..dbd8aa6 100755 --- a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp @@ -688,6 +688,8 @@ WindowBaseEcoreWl2::WindowBaseEcoreWl2( Dali::PositionSize positionSize, Any sur mBrightness( 0 ), mBrightnessChangeState( 0 ), mBrightnessChangeDone( true ), + mVisible( true ), + mWindowPositionSize( positionSize ), mOwnSurface( false ), mMoveResizeSerial( 0 ), mLastSubmittedMoveResizeSerial( 0 ) @@ -949,6 +951,9 @@ void WindowBaseEcoreWl2::OnRotation( void* data, int type, void* event ) rotationEvent.height = ev->w; } + mWindowPositionSize.width = rotationEvent.width; + mWindowPositionSize.height = rotationEvent.height; + mRotationSignal.Emit( rotationEvent ); } } @@ -1521,16 +1526,19 @@ bool WindowBaseEcoreWl2::IsEglWindowRotationSupported() void WindowBaseEcoreWl2::Move( PositionSize positionSize ) { + mWindowPositionSize = positionSize; ecore_wl2_window_position_set( mEcoreWindow, positionSize.x, positionSize.y ); } void WindowBaseEcoreWl2::Resize( PositionSize positionSize ) { + mWindowPositionSize = positionSize; ecore_wl2_window_geometry_set( mEcoreWindow, positionSize.x, positionSize.y, positionSize.width, positionSize.height ); } void WindowBaseEcoreWl2::MoveResize( PositionSize positionSize ) { + mWindowPositionSize = positionSize; ecore_wl2_window_sync_geometry_set( mEcoreWindow, ++mMoveResizeSerial, positionSize.x, positionSize.y, positionSize.width, positionSize.height ); } @@ -1580,11 +1588,18 @@ void WindowBaseEcoreWl2::SetAcceptFocus( bool accept ) void WindowBaseEcoreWl2::Show() { + if( !mVisible ) + { + ecore_wl2_window_geometry_set( mEcoreWindow, mWindowPositionSize.x, mWindowPositionSize.y, mWindowPositionSize.width, mWindowPositionSize.height ); + } + mVisible = true; + ecore_wl2_window_show( mEcoreWindow ); } void WindowBaseEcoreWl2::Hide() { + mVisible = false; ecore_wl2_window_hide( mEcoreWindow ); } diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h index c7a7240..f429435 100644 --- a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h @@ -496,6 +496,9 @@ private: uint32_t mBrightnessChangeState; bool mBrightnessChangeDone; + bool mVisible:1; + Dali::PositionSize mWindowPositionSize; + bool mOwnSurface; volatile uint32_t mMoveResizeSerial; -- 2.7.4 From 5167c1e4978ea61ffc8c3f74c15595b97662d347 Mon Sep 17 00:00:00 2001 From: Wonsik Jung Date: Tue, 2 Jun 2020 15:21:21 +0900 Subject: [PATCH 02/16] DALi Version 1.5.14 Change-Id: I2a694e23d32a43a58eba993458e54670a3373302 --- dali/public-api/dali-adaptor-version.cpp | 2 +- packaging/dali-adaptor.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dali/public-api/dali-adaptor-version.cpp b/dali/public-api/dali-adaptor-version.cpp index 5a65498..28b3ebd 100644 --- a/dali/public-api/dali-adaptor-version.cpp +++ b/dali/public-api/dali-adaptor-version.cpp @@ -28,7 +28,7 @@ namespace Dali const unsigned int ADAPTOR_MAJOR_VERSION = 1; const unsigned int ADAPTOR_MINOR_VERSION = 5; -const unsigned int ADAPTOR_MICRO_VERSION = 13; +const unsigned int ADAPTOR_MICRO_VERSION = 14; const char * const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index c5a2b63..acc28db 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -17,7 +17,7 @@ Name: dali-adaptor Summary: The DALi Tizen Adaptor -Version: 1.5.13 +Version: 1.5.14 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT -- 2.7.4 From d95e058075b693420f96b803425a14f994929d43 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Tue, 19 May 2020 17:32:25 +0900 Subject: [PATCH 03/16] Call PostRender method of the surface if needed Change-Id: Ic5651f52dfa42b08a4bc514af765188310f8f863 --- .../dali-test-suite-utils/test-application.cpp | 17 +++++++++++++---- .../dali-test-suite-utils/test-application.h | 1 + .../common/combined-update-render-controller.cpp | 11 ++++++++--- 3 files changed, 22 insertions(+), 7 deletions(-) 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 f85f14d..e8c0d12 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 @@ -188,9 +188,13 @@ bool TestApplication::Render( uint32_t intervalMilliseconds, const char* locatio { DoUpdate( intervalMilliseconds, location ); + // Reset the status + mRenderStatus.SetNeedsUpdate( false ); + mRenderStatus.SetNeedsPostRender( false ); + mCore->PreRender( mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/ ); - mCore->RenderScene( mScene, true /*render the off-screen buffers*/); - mCore->RenderScene( 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++; @@ -214,12 +218,17 @@ bool TestApplication::GetRenderNeedsUpdate() return mRenderStatus.NeedsUpdate(); } +bool TestApplication::GetRenderNeedsPostRender() +{ + return mRenderStatus.NeedsPostRender(); +} + bool TestApplication::RenderOnly( ) { // Update Time values mCore->PreRender( mRenderStatus, false /*do not force clear*/, false /*do not skip rendering*/ ); - mCore->RenderScene( mScene, true /*render the off-screen buffers*/); - mCore->RenderScene( 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 a922e23..e96f759 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 @@ -74,6 +74,7 @@ public: bool RenderOnly( ); void ResetContext(); bool GetRenderNeedsUpdate(); + bool GetRenderNeedsPostRender(); uint32_t Wait( uint32_t durationToWait ); static void EnableLogging( bool enabled ) { diff --git a/dali/internal/adaptor/common/combined-update-render-controller.cpp b/dali/internal/adaptor/common/combined-update-render-controller.cpp index 0e20903..b310671 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.cpp +++ b/dali/internal/adaptor/common/combined-update-render-controller.cpp @@ -741,18 +741,23 @@ void CombinedUpdateRenderController::UpdateRenderThread() if ( scene && windowSurface ) { + Integration::RenderStatus windowRenderStatus; + windowSurface->InitializeGraphics(); // Render off-screen frame buffers first if any - mCore.RenderScene( scene, true ); + mCore.RenderScene( windowRenderStatus, scene, true ); // Switch to the EGL context of the surface windowSurface->PreRender( surfaceResized ); // Switch GL context // Render the surface - mCore.RenderScene( scene, false ); + mCore.RenderScene( windowRenderStatus, scene, false ); - windowSurface->PostRender( false, false, surfaceResized ); // Swap Buffer + if( windowRenderStatus.NeedsPostRender() ) + { + windowSurface->PostRender( false, false, surfaceResized ); // Swap Buffer + } } } } -- 2.7.4 From 7e12b804069b4baedfbd6588cd238b4d5406e680 Mon Sep 17 00:00:00 2001 From: Joogab Yun Date: Mon, 8 Jun 2020 19:10:06 +0900 Subject: [PATCH 04/16] DALi Version 1.5.15 Change-Id: I3b8b0f9bb1d4d3ff852a88d552e9f030f7f845ab --- dali/public-api/dali-adaptor-version.cpp | 2 +- packaging/dali-adaptor.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dali/public-api/dali-adaptor-version.cpp b/dali/public-api/dali-adaptor-version.cpp index 28b3ebd..d89bb3f 100644 --- a/dali/public-api/dali-adaptor-version.cpp +++ b/dali/public-api/dali-adaptor-version.cpp @@ -28,7 +28,7 @@ namespace Dali const unsigned int ADAPTOR_MAJOR_VERSION = 1; const unsigned int ADAPTOR_MINOR_VERSION = 5; -const unsigned int ADAPTOR_MICRO_VERSION = 14; +const unsigned int ADAPTOR_MICRO_VERSION = 15; const char * const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index acc28db..7a83814 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -17,7 +17,7 @@ Name: dali-adaptor Summary: The DALi Tizen Adaptor -Version: 1.5.14 +Version: 1.5.15 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT -- 2.7.4 From 62b1236eb4b8dea02d1c6e6d952a904de83ddd5f Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Mon, 8 Jun 2020 18:41:09 +0900 Subject: [PATCH 05/16] Throw an exception if the Adaptor is not instantiated Change-Id: I707c2d351d4c28cfb05954cdd6d59c08269d8024 --- dali/internal/adaptor/common/adaptor.cpp | 4 ++++ dali/internal/system/linux/timer-impl-ecore.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dali/internal/adaptor/common/adaptor.cpp b/dali/internal/adaptor/common/adaptor.cpp index e77dea8..9551d82 100755 --- a/dali/internal/adaptor/common/adaptor.cpp +++ b/dali/internal/adaptor/common/adaptor.cpp @@ -107,21 +107,25 @@ void Adaptor::Stop() bool Adaptor::AddIdle( CallbackBase* callback, bool hasReturnValue ) { + DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" ); return mImpl->AddIdle( callback, hasReturnValue, false ); } bool Adaptor::AddWindow( Dali::Integration::SceneHolder childWindow, const std::string& childWindowName, const std::string& childWindowClassName, bool childWindowMode ) { + DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" ); return mImpl->AddWindow( childWindow, childWindowName, childWindowClassName, childWindowMode ); } void Adaptor::RemoveIdle( CallbackBase* callback ) { + DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" ); mImpl->RemoveIdle( callback ); } void Adaptor::ProcessIdle() { + DALI_ASSERT_ALWAYS( IsAvailable() && "Adaptor not instantiated" ); mImpl->ProcessIdle(); } diff --git a/dali/internal/system/linux/timer-impl-ecore.cpp b/dali/internal/system/linux/timer-impl-ecore.cpp index fde050d..7ebea28 100644 --- a/dali/internal/system/linux/timer-impl-ecore.cpp +++ b/dali/internal/system/linux/timer-impl-ecore.cpp @@ -81,7 +81,7 @@ Timer::~Timer() void Timer::Start() { // Timer should be used in the event thread - DALI_ASSERT_DEBUG( Adaptor::IsAvailable() ); + DALI_ASSERT_ALWAYS( Adaptor::IsAvailable() ); if(mImpl->mId != NULL) { @@ -94,7 +94,7 @@ void Timer::Start() void Timer::Stop() { // Timer should be used in the event thread - DALI_ASSERT_DEBUG( Adaptor::IsAvailable() ); + DALI_ASSERT_ALWAYS( Adaptor::IsAvailable() ); ResetTimerData(); } @@ -102,7 +102,7 @@ void Timer::Stop() void Timer::Pause() { // Timer should be used in the event thread - DALI_ASSERT_DEBUG( Adaptor::IsAvailable() ); + DALI_ASSERT_ALWAYS( Adaptor::IsAvailable() ); if( mImpl->mId != NULL ) { @@ -113,7 +113,7 @@ void Timer::Pause() void Timer::Resume() { // Timer should be used in the event thread - DALI_ASSERT_DEBUG( Adaptor::IsAvailable() ); + DALI_ASSERT_ALWAYS( Adaptor::IsAvailable() ); if( mImpl->mId != NULL ) { -- 2.7.4 From 0e9c6d5b7970bf6f385efa3c9b2173cce83c3da0 Mon Sep 17 00:00:00 2001 From: neostom432 Date: Tue, 16 Jun 2020 02:15:02 +0900 Subject: [PATCH 06/16] DALi Version 1.5.16 Change-Id: I7380bcff70ae49949edf1fc1283e88533206fd16 --- dali/public-api/dali-adaptor-version.cpp | 2 +- packaging/dali-adaptor.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dali/public-api/dali-adaptor-version.cpp b/dali/public-api/dali-adaptor-version.cpp index d89bb3f..e5ef10f 100644 --- a/dali/public-api/dali-adaptor-version.cpp +++ b/dali/public-api/dali-adaptor-version.cpp @@ -28,7 +28,7 @@ namespace Dali const unsigned int ADAPTOR_MAJOR_VERSION = 1; const unsigned int ADAPTOR_MINOR_VERSION = 5; -const unsigned int ADAPTOR_MICRO_VERSION = 15; +const unsigned int ADAPTOR_MICRO_VERSION = 16; const char * const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index 7a83814..706b1fd 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -17,7 +17,7 @@ Name: dali-adaptor Summary: The DALi Tizen Adaptor -Version: 1.5.15 +Version: 1.5.16 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT -- 2.7.4 From 31b3e92ff29394d14bcf9ff95b8a1e33173fd784 Mon Sep 17 00:00:00 2001 From: "huiyu.eun" Date: Tue, 16 Jun 2020 15:44:24 +0900 Subject: [PATCH 07/16] Change unsetenv to setenv unsetenv("AUL_LOADER_INIT") -> setenv("AUL_LOADER_INIT", "0", "1") Change-Id: If5420fc0a3baed766f03486ae14571bdd3d87212 Signed-off-by: huiyu.eun --- dali/internal/adaptor/tizen-wayland/framework-tizen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp index c440eeb..1a05da1 100644 --- a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp +++ b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp @@ -401,7 +401,7 @@ struct Framework::Impl if(getenv("AUL_LOADER_INIT")) { - unsetenv("AUL_LOADER_INIT"); + setenv("AUL_LOADER_INIT", "0", 1); ecore_shutdown(); } } -- 2.7.4 From 6fca3747046705fdbebd72f6fe7f86aada43d707 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Thu, 18 Jun 2020 15:42:22 +0900 Subject: [PATCH 08/16] Fix feedback sound API mm_sound_play_keysound() should be use with mm_sound_stop_keysound(). Change-Id: I4197a848508e12f880b30bded19d8c918b1af7bb --- plugins/dali-feedback.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/dali-feedback.cpp b/plugins/dali-feedback.cpp index c53935f..68dcc04 100644 --- a/plugins/dali-feedback.cpp +++ b/plugins/dali-feedback.cpp @@ -82,7 +82,7 @@ int DaliFeedback::PlaySound( const std::string& fileName ) void DaliFeedback::StopSound( int handle ) { - int errorCode = mm_sound_stop_sound( handle ); + int errorCode = mm_sound_stop_keysound( NULL ); if( errorCode < 0 ) { DEBUG_PRINTF( "StopSound() handle = %d failed with error code = %d\n", handle, errorCode); -- 2.7.4 From af634906664f835cd54f971dfe4bdf07216acb91 Mon Sep 17 00:00:00 2001 From: Joogab Yun Date: Wed, 17 Jun 2020 16:13:03 +0900 Subject: [PATCH 09/16] The advance of the letters is too narrow. So, remove the floor. Change-Id: Iae4c426819d7002ad1e4c7aab74818a3ef82aa30 --- dali/internal/text/text-abstraction/shaping-impl.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dali/internal/text/text-abstraction/shaping-impl.cpp b/dali/internal/text/text-abstraction/shaping-impl.cpp index b785c02..da78f59 100755 --- a/dali/internal/text/text-abstraction/shaping-impl.cpp +++ b/dali/internal/text/text-abstraction/shaping-impl.cpp @@ -249,10 +249,10 @@ struct Shaping::Plugin const GlyphIndex index = rtlIndex + j; mIndices.PushBack( glyphInfo[index].codepoint ); - mAdvance.PushBack( floor( glyphPositions[index].x_advance * FROM_266 ) ); + mAdvance.PushBack( glyphPositions[index].x_advance * FROM_266 ); mCharacterMap.PushBack( glyphInfo[index].cluster ); - mOffset.PushBack( floor( glyphPositions[index].x_offset * FROM_266 ) ); - mOffset.PushBack( floor( glyphPositions[index].y_offset * FROM_266 ) ); + mOffset.PushBack( glyphPositions[index].x_offset * FROM_266 ); + mOffset.PushBack( glyphPositions[index].y_offset * FROM_266 ); } i += numberOfGlyphsInCluster; @@ -260,10 +260,10 @@ struct Shaping::Plugin else { mIndices.PushBack( glyphInfo[i].codepoint ); - mAdvance.PushBack( floor( glyphPositions[i].x_advance * FROM_266 ) ); + mAdvance.PushBack( glyphPositions[i].x_advance * FROM_266 ); mCharacterMap.PushBack( glyphInfo[i].cluster ); - mOffset.PushBack( floor( glyphPositions[i].x_offset * FROM_266 ) ); - mOffset.PushBack( floor( glyphPositions[i].y_offset * FROM_266 ) ); + mOffset.PushBack( glyphPositions[i].x_offset * FROM_266 ); + mOffset.PushBack( glyphPositions[i].y_offset * FROM_266 ); ++i; } -- 2.7.4 From aa35ce5329eb4bc15b19d919f6ce7d0ceb64be7a Mon Sep 17 00:00:00 2001 From: Anton Obzhirov Date: Tue, 14 Apr 2020 16:00:16 +0100 Subject: [PATCH 10/16] Partial update implementation, first phase. Change-Id: I222a1972d5727f6e01bb941b08339c38aad1546a --- .../dali-test-suite-utils/test-application.cpp | 38 ++- .../dali-test-suite-utils/test-application.h | 6 +- .../src/dali-adaptor/utc-Dali-Window.cpp | 18 ++ dali/devel-api/adaptor-framework/window-devel.cpp | 5 + dali/devel-api/adaptor-framework/window-devel.h | 15 +- .../adaptor-framework/render-surface-interface.h | 7 +- .../adaptor-framework/scene-holder-impl.cpp | 15 ++ dali/internal/adaptor/common/adaptor-impl.cpp | 3 +- .../common/combined-update-render-controller.cpp | 25 +- .../common/combined-update-render-controller.h | 2 + dali/internal/graphics/common/graphics-interface.h | 14 +- dali/internal/graphics/gles/egl-graphics.cpp | 13 +- dali/internal/graphics/gles/egl-graphics.h | 10 + dali/internal/graphics/gles/egl-implementation.cpp | 293 ++++++++++++++++++++- dali/internal/graphics/gles/egl-implementation.h | 48 +++- .../internal/system/common/environment-options.cpp | 18 +- dali/internal/system/common/environment-options.h | 6 + .../internal/system/common/environment-variables.h | 2 + dali/internal/window-system/common/window-impl.cpp | 106 ++++++++ dali/internal/window-system/common/window-impl.h | 5 + .../window-system/common/window-render-surface.cpp | 21 +- .../window-system/common/window-render-surface.h | 4 +- .../native-render-surface-ecore-wl.cpp | 22 +- .../tizen-wayland/native-render-surface-ecore-wl.h | 4 +- .../ubuntu-x11/pixmap-render-surface-ecore-x.cpp | 4 +- .../ubuntu-x11/pixmap-render-surface-ecore-x.h | 4 +- 26 files changed, 664 insertions(+), 44 deletions(-) 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() -- 2.7.4 From 4461208a8cf11f6c1765cc0fd81a8c46c0cd9b8d Mon Sep 17 00:00:00 2001 From: Sunghyun Kim Date: Mon, 22 Jun 2020 17:33:09 +0900 Subject: [PATCH 11/16] DALi Version 1.5.17 Change-Id: Ided273236003f8c233c282275d26259bfce35d8c --- dali/public-api/dali-adaptor-version.cpp | 2 +- packaging/dali-adaptor.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dali/public-api/dali-adaptor-version.cpp b/dali/public-api/dali-adaptor-version.cpp index e5ef10f..0fce620 100644 --- a/dali/public-api/dali-adaptor-version.cpp +++ b/dali/public-api/dali-adaptor-version.cpp @@ -28,7 +28,7 @@ namespace Dali const unsigned int ADAPTOR_MAJOR_VERSION = 1; const unsigned int ADAPTOR_MINOR_VERSION = 5; -const unsigned int ADAPTOR_MICRO_VERSION = 16; +const unsigned int ADAPTOR_MICRO_VERSION = 17; const char * const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index 706b1fd..6523580 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -17,7 +17,7 @@ Name: dali-adaptor Summary: The DALi Tizen Adaptor -Version: 1.5.16 +Version: 1.5.17 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT -- 2.7.4 From 589ec1d7fa9d28ddd347b86bef3a730cecebc047 Mon Sep 17 00:00:00 2001 From: "huiyu.eun" Date: Mon, 25 Nov 2019 17:58:43 +0900 Subject: [PATCH 12/16] Add Component Application Structure Add Component Application Structure Change-Id: I6d37796b495db417f81d0cd14dd66818c0d69ba4 Signed-off-by: huiyu.eun --- build/tizen/deps-check.cmake | 7 ++ build/tizen/profiles/common-profile.cmake | 7 ++ build/tizen/profiles/ivi-profile.cmake | 7 ++ build/tizen/profiles/mobile-profile.cmake | 6 + build/tizen/profiles/tv-profile.cmake | 7 ++ build/tizen/profiles/wearable-profile.cmake | 7 ++ .../adaptor-framework/component-application.h | 127 +++++++++++++++++++++ dali/devel-api/file.list | 2 +- dali/internal/adaptor/common/framework.h | 13 ++- dali/internal/adaptor/file.list | 5 +- .../tizen-wayland/component-application-impl.cpp | 53 +++++++++ .../tizen-wayland/component-application-impl.h | 111 ++++++++++++++++++ .../tizen-wayland/component-application.cpp | 53 +++++++++ .../adaptor/tizen-wayland/framework-tizen.cpp | 121 ++++++++++++++++---- dali/public-api/file.list | 2 +- packaging/dali-adaptor.spec | 6 +- 16 files changed, 505 insertions(+), 29 deletions(-) create mode 100644 dali/devel-api/adaptor-framework/component-application.h create mode 100644 dali/internal/adaptor/tizen-wayland/component-application-impl.cpp create mode 100644 dali/internal/adaptor/tizen-wayland/component-application-impl.h create mode 100644 dali/internal/adaptor/tizen-wayland/component-application.cpp diff --git a/build/tizen/deps-check.cmake b/build/tizen/deps-check.cmake index b496dd9..ac5382a 100644 --- a/build/tizen/deps-check.cmake +++ b/build/tizen/deps-check.cmake @@ -89,6 +89,7 @@ CHECK_MODULE_AND_SET( CAPI_SYSTEM_INFO capi-system-info [] ) CHECK_MODULE_AND_SET( CAPI_SYSTEM_SENSOR capi-system-sensor capi_system_sensor_support ) CHECK_MODULE_AND_SET( CAPI_SYSTEM_SYSTEM_SETTINGS capi-system-system-settings [] ) CHECK_MODULE_AND_SET( CAPI_APPFW_APPLICATION capi-appfw-application [] ) +CHECK_MODULE_AND_SET( COMPONENT_BASED_CORE_BASE component-based-core-base [] ) CHECK_MODULE_AND_SET( ELEMENTARY elementary [] ) CHECK_MODULE_AND_SET( BUNDLE bundle [] ) @@ -211,6 +212,10 @@ ELSE() SET( cachePath /home/owner ) ENDIF() +IF( enable_appfw ) + ADD_DEFINITIONS( -DUSE_APPFW -DCOMPONENT_APPLICATION_SUPPORT) +ENDIF() + ####################################################### ADD_DEFINITIONS( -DDALI_PROFILE_${enable_profile}) @@ -330,6 +335,7 @@ IF( enable_appfw ) ${CAPI_APPFW_WIDGET_BASE_CFLAGS} ${ECORE_IMF_CFLAGS} ${FRIBIDI_CFLAGS} + ${COMPONENT_BASED_CORE_BASE_CFLAGS} ) SET( DALI_LDFLAGS ${DALI_LDFLAGS} @@ -344,6 +350,7 @@ IF( enable_appfw ) ${CAPI_APPFW_WIDGET_BASE_LDFLAGS} ${ECORE_IMF_LDFLAGS} ${FRIBIDI_LDFLAGS} + ${COMPONENT_BASED_CORE_BASE_LDFLAGS} ) ELSE() SET( DALI_CFLAGS ${DALI_CFLAGS} diff --git a/build/tizen/profiles/common-profile.cmake b/build/tizen/profiles/common-profile.cmake index 2c18ce0..bdc26ff 100644 --- a/build/tizen/profiles/common-profile.cmake +++ b/build/tizen/profiles/common-profile.cmake @@ -65,3 +65,10 @@ IF( ENABLE_TRACE ) ${adaptor_trace_tizen_src_files} ) ENDIF() + +IF( COMPONENT_APPLICATION_SUPPORT ) + SET( SOURCES ${SOURCES} + ${adaptor_adaptor_component_application_src_files} + ) +ENDIF() + diff --git a/build/tizen/profiles/ivi-profile.cmake b/build/tizen/profiles/ivi-profile.cmake index 765a1ea..77d540c 100644 --- a/build/tizen/profiles/ivi-profile.cmake +++ b/build/tizen/profiles/ivi-profile.cmake @@ -66,3 +66,10 @@ IF( ENABLE_TRACE ) ${adaptor_trace_tizen_src_files} ) ENDIF() + +IF( COMPONENT_APPLICATION_SUPPORT ) + SET( SOURCES ${SOURCES} + ${adaptor_adaptor_component_application_src_files} + ) +ENDIF() + diff --git a/build/tizen/profiles/mobile-profile.cmake b/build/tizen/profiles/mobile-profile.cmake index 38cc849..0ba3e35 100644 --- a/build/tizen/profiles/mobile-profile.cmake +++ b/build/tizen/profiles/mobile-profile.cmake @@ -66,3 +66,9 @@ IF( ENABLE_TRACE ) ) ENDIF() +IF( COMPONENT_APPLICATION_SUPPORT ) + SET( SOURCES ${SOURCES} + ${adaptor_adaptor_component_application_src_files} + ) +ENDIF() + diff --git a/build/tizen/profiles/tv-profile.cmake b/build/tizen/profiles/tv-profile.cmake index fbaa533..ff4b008 100644 --- a/build/tizen/profiles/tv-profile.cmake +++ b/build/tizen/profiles/tv-profile.cmake @@ -65,3 +65,10 @@ IF( ENABLE_TRACE ) ${adaptor_trace_tizen_src_files} ) ENDIF() + +IF( COMPONENT_APPLICATION_SUPPORT ) + SET( SOURCES ${SOURCES} + ${adaptor_adaptor_component_application_src_files} + ) +ENDIF() + diff --git a/build/tizen/profiles/wearable-profile.cmake b/build/tizen/profiles/wearable-profile.cmake index 3682664..7d5b1b4 100644 --- a/build/tizen/profiles/wearable-profile.cmake +++ b/build/tizen/profiles/wearable-profile.cmake @@ -67,3 +67,10 @@ IF( ENABLE_TRACE ) ${adaptor_trace_tizen_src_files} ) ENDIF() + +IF( COMPONENT_APPLICATION_SUPPORT ) + SET( SOURCES ${SOURCES} + ${adaptor_adaptor_component_application_src_files} + ) +ENDIF() + diff --git a/dali/devel-api/adaptor-framework/component-application.h b/dali/devel-api/adaptor-framework/component-application.h new file mode 100644 index 0000000..1f23b2f --- /dev/null +++ b/dali/devel-api/adaptor-framework/component-application.h @@ -0,0 +1,127 @@ +#ifndef DALI_COMPONENT_APPLICATION_H +#define DALI_COMPONENT_APPLICATION_H + +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Internal DALI_INTERNAL +{ + +namespace Adaptor +{ +class ComponentApplication; +} + +} + +/** + * @brief An ComponentApplication class object should be created by every component-based application + * that wishes to use Dali. + * + * Component application draw multiple UI applications based on frame components. + * component application can draw multiple UIs in one process. + * + * It provides a means for initializing the + * resources required by the Dali::Core. + * + * The ComponentApplication class emits several signals which the user can + * connect to. The user should not create any Dali objects in the main + * function and instead should connect to the Init signal of the + * ComponentApplication and create the Dali Widget object in the connected callback. + * + */ +class DALI_ADAPTOR_API ComponentApplication : public Application +{ +public: + typedef Signal< Any () > CreateSignalType; + +public: + /** + * @brief This is the constructor for component applications without an argument list. + * @return A handle to the ComponentApplication + */ + static ComponentApplication New( ); + + /** + * @brief This is the constructor for component applications. + * + * @param[in,out] argc A pointer to the number of arguments + * @param[in,out] argv A pointer to the argument list + * @return A handle to the ComponentApplication + */ + static ComponentApplication New( int* argc, char **argv[] ); + + /** + * @brief This is the constructor for component applications with a stylesheet + * + * @param[in,out] argc A pointer to the number of arguments + * @param[in,out] argv A pointer to the argument list + * @param[in] stylesheet The path to user defined theme file + * @return A handle to the ComponentApplication + */ + static ComponentApplication New( int* argc, char **argv[], const std::string& stylesheet ); + + /** + * @brief The default constructor. + */ + ComponentApplication() = default; + + /** + * @brief Copy Constructor. + * + * @param[in] componentApplication Handle to an object + */ + ComponentApplication( const ComponentApplication& componentApplication ) = default; + + /** + * @brief Assignment operator. + * + * @param[in] componentApplication Handle to an object + * @return A reference to this + */ + ComponentApplication& operator=( const ComponentApplication& componentApplication ) = default; + + /** + * @brief Destructor + */ + ~ComponentApplication() = default; + + /** + * @brief The user should connect to this signal to determine when they should initialize + * their application. + * The callback function is called before the main loop of the application starts. + * @return The signal to connect to + */ + CreateSignalType& CreateSignal(); + +public: + /// @cond internal + /** + * @brief Internal constructor. + */ + explicit DALI_INTERNAL ComponentApplication(Internal::Adaptor::ComponentApplication* componentApplication); + /// @endcond +}; +} // namespace Dali + +#endif // DALI_COMPONENT_APPLICATION_H + diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list index 33c3ab3..b7e8f1f 100755 --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -84,6 +84,7 @@ SET( devel_api_adaptor_framework_header_files ${adaptor_devel_api_dir}/adaptor-framework/key-devel.h ${adaptor_devel_api_dir}/adaptor-framework/thread-settings.h ${adaptor_devel_api_dir}/adaptor-framework/window-devel.h + ${adaptor_devel_api_dir}/adaptor-framework/component-application.h ) @@ -117,4 +118,3 @@ SET( text_abstraction_header_files ${adaptor_devel_api_dir}/text-abstraction/text-renderer.h ${adaptor_devel_api_dir}/text-abstraction/text-renderer-layout-helper.h ) - diff --git a/dali/internal/adaptor/common/framework.h b/dali/internal/adaptor/common/framework.h index d95388c..e4b172b 100644 --- a/dali/internal/adaptor/common/framework.h +++ b/dali/internal/adaptor/common/framework.h @@ -28,6 +28,9 @@ // INTERNAL INCLUDES #include #include +#ifdef COMPONENT_APPLICATION_SUPPORT +#include +#endif namespace Dali { @@ -54,7 +57,8 @@ public: { NORMAL, ///< normal appFramework WATCH, ///< watch appFramework - WIDGET ///< widget appFramework + WIDGET, ///< widget appFramework + COMPONENT ///< component appFramework }; /** @@ -141,6 +145,13 @@ public: * Invoked when the platform surface is destroyed. */ virtual void OnSurfaceDestroyed( Any newSurface ) {} + +#ifdef COMPONENT_APPLICATION_SUPPORT + /** + * Invoked when the component application is created. + */ + virtual Any OnCreate() { return nullptr; } +#endif }; public: diff --git a/dali/internal/adaptor/file.list b/dali/internal/adaptor/file.list index defd518..cf5b02c 100644 --- a/dali/internal/adaptor/file.list +++ b/dali/internal/adaptor/file.list @@ -48,4 +48,7 @@ SET( adaptor_adaptor_windows_src_files ${adaptor_adaptor_dir}/windows/framework-win.cpp ) - +SET( adaptor_adaptor_component_application_src_files + ${adaptor_adaptor_dir}/tizen-wayland/component-application.cpp + ${adaptor_adaptor_dir}/tizen-wayland/component-application-impl.cpp +) diff --git a/dali/internal/adaptor/tizen-wayland/component-application-impl.cpp b/dali/internal/adaptor/tizen-wayland/component-application-impl.cpp new file mode 100644 index 0000000..bf3855c --- /dev/null +++ b/dali/internal/adaptor/tizen-wayland/component-application-impl.cpp @@ -0,0 +1,53 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ +ComponentApplicationPtr ComponentApplication::New( + int* argc, + char **argv[], + const std::string& stylesheet, + Dali::Application::WINDOW_MODE windowMode) +{ + ComponentApplicationPtr application ( new ComponentApplication (argc, argv, stylesheet, windowMode ) ); + return application; +} + +ComponentApplication::ComponentApplication( int* argc, char** argv[], const std::string& stylesheet, Dali::Application::WINDOW_MODE windowMode ) +: Application(argc, argv, stylesheet, windowMode, PositionSize(), Framework::COMPONENT) +{ +} + +Any ComponentApplication::OnCreate() +{ + return mCreateSignal.Emit(); +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali diff --git a/dali/internal/adaptor/tizen-wayland/component-application-impl.h b/dali/internal/adaptor/tizen-wayland/component-application-impl.h new file mode 100644 index 0000000..cd7e6c2 --- /dev/null +++ b/dali/internal/adaptor/tizen-wayland/component-application-impl.h @@ -0,0 +1,111 @@ +#ifndef DALI_INTERNAL_COMPONENT_APPLICATION_H +#define DALI_INTERNAL_COMPONENT_APPLICATION_H + +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +class Adaptor; + +namespace Internal +{ + +namespace Adaptor +{ + +class ComponentApplication; +typedef IntrusivePtr ComponentApplicationPtr; + +/** + * Implementation of the ComponentApplication class. + */ +class ComponentApplication : public Application +{ +public: + typedef Dali::ComponentApplication::CreateSignalType CreateSignal; + +public: + /** + * Create a new component application + * @param[in] argc A pointer to the number of arguments + * @param[in] argv A pointer to the argument list + * @param[in] stylesheet The path to user defined theme file + * @param[in] windowMode A member of WINDOW_MODE + * @return A handle to the ComponentApplication + */ + static ComponentApplicationPtr New( int* argc, char **argv[], const std::string& stylesheet, WINDOW_MODE windowMode ); + + /** + * @brief The default constructor. + */ + ComponentApplication( int* argc, char **argv[], const std::string& stylesheet, WINDOW_MODE windowMode ); + + /** + * @brief Undefined copy constructor. + */ + ComponentApplication( const ComponentApplication& ) = default; + + /** + * @brief Destructor + */ + virtual ~ComponentApplication() = default; + + /** + *@brief Undefined assignment operator. + */ + ComponentApplication& operator=( const ComponentApplication& ) = delete; + +public: // From Framework::Observer + /** + * Called when the framework is Component Application Created. + */ + virtual Any OnCreate(); + +public: + CreateSignal mCreateSignal; +}; + +inline ComponentApplication& GetImplementation(Dali::ComponentApplication& application) +{ + DALI_ASSERT_ALWAYS(application && "application handle is empty"); + + BaseObject& handle = application.GetBaseObject(); + + return static_cast(handle); +} + +inline const ComponentApplication& GetImplementation(const Dali::ComponentApplication& application) +{ + DALI_ASSERT_ALWAYS(application && "application handle is empty"); + + const BaseObject& handle = application.GetBaseObject(); + + return static_cast(handle); +} + + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali +#endif diff --git a/dali/internal/adaptor/tizen-wayland/component-application.cpp b/dali/internal/adaptor/tizen-wayland/component-application.cpp new file mode 100644 index 0000000..c1e0761 --- /dev/null +++ b/dali/internal/adaptor/tizen-wayland/component-application.cpp @@ -0,0 +1,53 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +ComponentApplication ComponentApplication::New() +{ + return New( NULL, NULL ); +} + +ComponentApplication ComponentApplication::New( int* argc, char **argv[] ) +{ + return New( argc, argv, "" ); +} + +ComponentApplication ComponentApplication::New( int* argc, char **argv[], const std::string& stylesheet ) +{ + Internal::Adaptor::ComponentApplicationPtr internal = Internal::Adaptor::ComponentApplication::New( argc, argv, stylesheet, TRANSPARENT ); + return ComponentApplication(internal.Get()); +} + +ComponentApplication::CreateSignalType& ComponentApplication::CreateSignal() +{ + return Internal::Adaptor::GetImplementation(*this).mCreateSignal; +} + +ComponentApplication::ComponentApplication(Internal::Adaptor::ComponentApplication* implementation) +: Application(implementation) +{ +} + +} // namespace Dali diff --git a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp index 1a05da1..d4236cf 100644 --- a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp +++ b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp @@ -41,6 +41,10 @@ #include #endif // TIZEN_PLATFORM_CONFIG_SUPPORTED +#ifdef COMPONENT_APPLICATION_SUPPORT +#include +#endif + #include // INTERNAL INCLUDES @@ -222,35 +226,60 @@ struct Framework::Impl int AppMain() { int ret; - - if (mApplicationType == NORMAL) - { - ret = AppNormalMain(); - } - else if(mApplicationType == WIDGET) + switch ( mApplicationType ) { - ret = AppWidgetMain(); - } - else - { - ret = AppWatchMain(); + case NORMAL: + { + ret = AppNormalMain(); + break; + } + case WIDGET: + { + ret = AppWidgetMain(); + break; + } + case WATCH: + { + ret = AppWatchMain(); + break; + } +#ifdef COMPONENT_APPLICATION_SUPPORT + case COMPONENT: + { + ret = AppComponentMain(); + break; + } +#endif } return ret; } void AppExit() { - if (mApplicationType == NORMAL) - { - AppNormalExit(); - } - else if(mApplicationType == WIDGET) + switch ( mApplicationType ) { - AppWidgetExit(); - } - else - { - AppWatchExit(); + case NORMAL: + { + AppNormalExit(); + break; + } + case WIDGET: + { + AppWidgetExit(); + break; + } + case WATCH: + { + AppWatchExit(); + break; + } +#ifdef COMPONENT_APPLICATION_SUPPORT + case COMPONENT: + { + AppComponentExit(); + break; + } +#endif } } @@ -697,6 +726,56 @@ struct Framework::Impl #endif } +#ifdef COMPONENT_APPLICATION_SUPPORT + int AppComponentMain() + { + int ret; + + /*Crate component_based_app_base_lifecycle_callback*/ + component_based_app_base_lifecycle_callback_s callback; + callback.init = AppInit; + callback.run = AppRun; + callback.exit = AppExit; + callback.create = ComponentAppCreate; + callback.terminate = ComponentAppTerminate; + callback.fini = ComponentAppFinish; + + return component_based_app_base_main(*mFramework->mArgc, *mFramework->mArgv, &callback, mFramework);; + } + + static void* ComponentAppCreate( void *data ) + { + Framework* framework = static_cast(data); + Observer *observer = &framework->mObserver; + observer->OnInit(); + + return Dali::AnyCast( observer->OnCreate() ); + } + + static void ComponentAppTerminate( void *data ) + { + Observer *observer = &static_cast(data)->mObserver; + observer->OnTerminate(); + } + + static void ComponentAppFinish( void *data ) + { + ecore_shutdown(); + + if(getenv("AUL_LOADER_INIT")) + { + setenv("AUL_LOADER_INIT", "0", 1); + ecore_shutdown(); + } + } + + void AppComponentExit() + { + component_based_app_base_exit(); + } + +#endif + private: // Undefined Impl( const Impl& impl ); diff --git a/dali/public-api/file.list b/dali/public-api/file.list index 71866f1..e4d3ac3 100644 --- a/dali/public-api/file.list +++ b/dali/public-api/file.list @@ -54,4 +54,4 @@ SET( adaptor_dali_wearable_header_file SET( public_dali_watch_header_files ${adaptor_public_api_dir}/watch/watch-application.h ${adaptor_public_api_dir}/watch/watch-time.h -) \ No newline at end of file +) diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index 6523580..0e7a469 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -103,6 +103,7 @@ BuildRequires: pkgconfig(capi-system-system-settings) # for feedback plugin BuildRequires: pkgconfig(mm-sound) BuildRequires: pkgconfig(feedback) +BuildRequires: pkgconfig(component-based-core-base) # for multiprofile Requires: %{name}-compat = %{version}-%{release} @@ -277,10 +278,6 @@ cmake_flags+=" -DCMAKE_BUILD_TYPE=Debug" cmake_flags+=" -DENABLE_TRACE=ON" %endif -%if 0%{?enable_appfw} -cmake_flags+=" -DUSE_APPFW" -%endif - libtoolize --force cd %{_builddir}/%{name}-%{version}/build/tizen @@ -300,6 +297,7 @@ cmake_flags+=" -DCMAKE_INSTALL_INCLUDEDIR=%{_includedir}" cmake_flags+=" -DENABLE_TIZEN_MAJOR_VERSION=%{tizen_version_major}" cmake_flags+=" -DENABLE_FEEDBACK=YES" cmake_flags+=" -DENABLE_APPFW=YES" +cmake_flags+=" -DCOMPONENT_APPLICATION_SUPPORT=YES" # Set up the build via Cmake ####################################################################### -- 2.7.4 From f5b4a7d0dcf0f95ea57931d7f891842e8c238c88 Mon Sep 17 00:00:00 2001 From: "Seungho, Baek" Date: Thu, 25 Jun 2020 11:22:36 +0900 Subject: [PATCH 13/16] Change target share directory from dali to dali-legacy Change-Id: Ie8ec3ef95b572487347c25d5cd80f078ab756509 Signed-off-by: Seungho, Baek --- build/tizen/deps-check.cmake | 4 ++-- packaging/dali-adaptor.spec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/tizen/deps-check.cmake b/build/tizen/deps-check.cmake index ac5382a..f22ceef 100644 --- a/build/tizen/deps-check.cmake +++ b/build/tizen/deps-check.cmake @@ -185,13 +185,13 @@ ENDIF() IF( DEFINED ENV{DALI_DATA_RW_DIR} ) SET( dataReadWriteDir $ENV{DALI_DATA_RW_DIR} ) ELSE() - SET( dataReadWriteDir ${CMAKE_INSTALL_PREFIX}/share/dali/ ) + SET( dataReadWriteDir ${CMAKE_INSTALL_PREFIX}/share/dali-legacy/ ) ENDIF() IF( DEFINED ENV{DALI_DATA_RO_DIR} ) SET( dataReadOnlyDir $ENV{DALI_DATA_RO_DIR} ) ELSE() - SET( dataReadOnlyDir ${CMAKE_INSTALL_PREFIX}/share/dali/ ) + SET( dataReadOnlyDir ${CMAKE_INSTALL_PREFIX}/share/dali-legacy/ ) ENDIF() IF( DEFINED ENV{TIZEN_PLATFORM_CONFIG_SUPPORTED} ) diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index 0e7a469..ddc0189 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -234,8 +234,8 @@ Feedback plugin to play haptic and audio feedback for Dali #Use TZ_PATH when tizen version is 3.x or greater -%define dali_data_rw_dir %TZ_SYS_RO_SHARE/dali/ -%define dali_data_ro_dir %TZ_SYS_RO_SHARE/dali/ +%define dali_data_rw_dir %TZ_SYS_RO_SHARE/dali-legacy/ +%define dali_data_ro_dir %TZ_SYS_RO_SHARE/dali-legacy/ %define font_preloaded_path %TZ_SYS_RO_SHARE/fonts/ %define font_downloaded_path %TZ_SYS_SHARE/fonts/ %define font_application_path %TZ_SYS_RO_SHARE/app_fonts/ -- 2.7.4 From bcc548aaa80f4401d414d9cde92550b57a8c569b Mon Sep 17 00:00:00 2001 From: "Seungho, Baek" Date: Wed, 10 Jun 2020 16:04:07 +0900 Subject: [PATCH 14/16] Support WebP format - Make animated-image-loading interface for gif and webp. - Animated WebP requires WEBP_DEMUX_ABI_VERSION 0x0107 or later Change-Id: I5331163e2b0d68a6ef7cb5a06d6e59a5140ffca9 Signed-off-by: Seungho, Baek --- .../src/dali-adaptor/utc-Dali-GifLoading.cpp | 60 +++-- build/tizen/CMakeLists.txt | 8 +- .../adaptor-framework/animated-image-loading.cpp | 91 +++++++ .../adaptor-framework/animated-image-loading.h | 150 +++++++++++ dali/devel-api/file.list | 4 +- .../imaging/common/animated-image-loading-impl.h | 118 ++++++++ .../imaging/common}/gif-loading.cpp | 45 ++-- .../imaging/common}/gif-loading.h | 60 ++--- dali/internal/imaging/common/webp-loading.cpp | 297 +++++++++++++++++++++ dali/internal/imaging/common/webp-loading.h | 121 +++++++++ dali/internal/imaging/file.list | 2 + packaging/dali-adaptor.spec | 4 + 12 files changed, 871 insertions(+), 89 deletions(-) create mode 100644 dali/devel-api/adaptor-framework/animated-image-loading.cpp create mode 100644 dali/devel-api/adaptor-framework/animated-image-loading.h create mode 100644 dali/internal/imaging/common/animated-image-loading-impl.h rename dali/{devel-api/adaptor-framework => internal/imaging/common}/gif-loading.cpp (97%) mode change 100755 => 100644 rename dali/{devel-api/adaptor-framework => internal/imaging/common}/gif-loading.h (62%) mode change 100755 => 100644 create mode 100644 dali/internal/imaging/common/webp-loading.cpp create mode 100644 dali/internal/imaging/common/webp-loading.h diff --git a/automated-tests/src/dali-adaptor/utc-Dali-GifLoading.cpp b/automated-tests/src/dali-adaptor/utc-Dali-GifLoading.cpp index 6a4fa87..b87ce8e 100755 --- a/automated-tests/src/dali-adaptor/utc-Dali-GifLoading.cpp +++ b/automated-tests/src/dali-adaptor/utc-Dali-GifLoading.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include using namespace Dali; @@ -50,38 +50,57 @@ void VerifyLoad( std::vector& pixelDataList, Dali::Vector pixelDataList; Dali::Vector frameDelayList; - std::unique_ptr gifLoading = GifLoading::New( gGif_100_None, true ); - bool succeed = gifLoading->LoadAllFrames( pixelDataList, frameDelayList ); + Dali::AnimatedImageLoading animatedImageLoading = Dali::AnimatedImageLoading::New( gGif_100_None, true ); + bool succeed = animatedImageLoading.LoadNextNFrames( 0u, animatedImageLoading.GetImageCount(), pixelDataList ); + frameDelayList.Clear(); + frameDelayList.Resize( animatedImageLoading.GetImageCount(), 0 ); + for( uint32_t i = 0; i < animatedImageLoading.GetImageCount(); ++i ) + { + frameDelayList[i] = animatedImageLoading.GetFrameInterval( i ); + } // Check that the loading succeed DALI_TEST_CHECK( succeed ); VerifyLoad( pixelDataList, frameDelayList, 5u, 100u, 100u, 1000u ); pixelDataList.clear(); - gifLoading = GifLoading::New( gGif_100_Prev, true ); - succeed = gifLoading->LoadAllFrames( pixelDataList, frameDelayList ); + animatedImageLoading = Dali::AnimatedImageLoading::New( gGif_100_Prev, true ); + succeed = animatedImageLoading.LoadNextNFrames( 0u, animatedImageLoading.GetImageCount(), pixelDataList ); + frameDelayList.Clear(); + frameDelayList.Resize( animatedImageLoading.GetImageCount(), 0 ); + for( uint32_t i = 0; i < animatedImageLoading.GetImageCount(); ++i ) + { + frameDelayList[i] = animatedImageLoading.GetFrameInterval( i ); + } + // Check that the loading succeed DALI_TEST_CHECK( succeed ); VerifyLoad( pixelDataList, frameDelayList, 5u, 100u, 100u, 1000u ); pixelDataList.clear(); - gifLoading = GifLoading::New( gGif_100_Bgnd, true ); - succeed = gifLoading->LoadAllFrames( pixelDataList, frameDelayList ); + animatedImageLoading = Dali::AnimatedImageLoading::New( gGif_100_Bgnd, true ); + succeed = animatedImageLoading.LoadNextNFrames( 0u, animatedImageLoading.GetImageCount(), pixelDataList ); + frameDelayList.Clear(); + frameDelayList.Resize( animatedImageLoading.GetImageCount(), 0 ); + for( uint32_t i = 0; i < animatedImageLoading.GetImageCount(); ++i ) + { + frameDelayList[i] = animatedImageLoading.GetFrameInterval( i ); + } // Check that the loading succeed DALI_TEST_CHECK( succeed ); @@ -90,28 +109,27 @@ int UtcDaliGifLoadingP(void) END_TEST; } -int UtcDaliGifLoadingN(void) +int UtcDaliAnimatedImageLoadingN(void) { std::vector pixelDataList; Dali::Vector frameDelayList; - std::unique_ptr gifLoading = GifLoading::New( gGifNonExist, true ); - bool succeed = gifLoading->LoadAllFrames( pixelDataList, frameDelayList ); + Dali::AnimatedImageLoading animatedImageLoading = Dali::AnimatedImageLoading::New( gGifNonExist, true ); + bool succeed = animatedImageLoading.LoadNextNFrames( 0u, animatedImageLoading.GetImageCount(), pixelDataList ); // Check that the loading failed DALI_TEST_CHECK( !succeed ); // Check that both pixelDataList and frameDelayList are empty DALI_TEST_EQUALS( pixelDataList.size(), 0u, TEST_LOCATION ); - DALI_TEST_EQUALS( frameDelayList.Size(), 0u, TEST_LOCATION ); END_TEST; } -int UtcDaliGifLoadingGetImageSizeP(void) +int UtcDaliAnimatedImageLoadingGetImageSizeP(void) { - std::unique_ptr gifLoading = GifLoading::New( gGif_100_None, true ); - ImageDimensions imageSize = gifLoading->GetImageSize(); + Dali::AnimatedImageLoading animatedImageLoading = Dali::AnimatedImageLoading::New( gGif_100_None, true ); + ImageDimensions imageSize = animatedImageLoading.GetImageSize(); // Check that the image size is [100, 100] DALI_TEST_EQUALS( imageSize.GetWidth(), 100u, TEST_LOCATION ); @@ -120,12 +138,12 @@ int UtcDaliGifLoadingGetImageSizeP(void) END_TEST; } -int UtcDaliGifLoadingGetImageSizeN(void) +int UtcDaliAnimatedImageLoadingGetImageSizeN(void) { - std::unique_ptr gifLoading = GifLoading::New( gGifNonExist, true ); - ImageDimensions imageSize = gifLoading->GetImageSize(); + Dali::AnimatedImageLoading animatedImageLoading = Dali::AnimatedImageLoading::New( gGifNonExist, true ); + ImageDimensions imageSize = animatedImageLoading.GetImageSize(); - // Check that it returns zero size when the gif is not valid + // Check that it returns zero size when the animated image is not valid DALI_TEST_EQUALS( imageSize.GetWidth(), 0u, TEST_LOCATION ); DALI_TEST_EQUALS( imageSize.GetHeight(), 0u, TEST_LOCATION ); diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt index 7c56a82..a83d807 100644 --- a/build/tizen/CMakeLists.txt +++ b/build/tizen/CMakeLists.txt @@ -176,11 +176,13 @@ IF( UNIX ) ENDIF() ENDIF() +SET( REQUIRED_LIBS ${REQUIRED_LIBS} webp webpdemux ) + TARGET_LINK_LIBRARIES( ${name} ${DALI_LDFLAGS} - ${REQUIRED_LIBS} - ${OPTIONAL_LIBS} - ${COVERAGE} + ${REQUIRED_LIBS} + ${OPTIONAL_LIBS} + ${COVERAGE} ) SET_TARGET_PROPERTIES( ${name} diff --git a/dali/devel-api/adaptor-framework/animated-image-loading.cpp b/dali/devel-api/adaptor-framework/animated-image-loading.cpp new file mode 100644 index 0000000..f2a9afa --- /dev/null +++ b/dali/devel-api/adaptor-framework/animated-image-loading.cpp @@ -0,0 +1,91 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// INTERNAL HEADER +#include +#include +#include + +namespace Dali +{ + +AnimatedImageLoading::AnimatedImageLoading() +{ +} + +AnimatedImageLoading AnimatedImageLoading::New( const std::string& url, bool isLocalResource ) +{ + + const std::size_t urlSize = url.length(); + + Internal::Adaptor::AnimatedImageLoadingPtr internal = NULL; + if(urlSize >= 4){ // Avoid throwing out_of_range or failing silently if exceptions are turned-off on the compare(). (http://www.cplusplus.com/reference/string/string/compare/) + if( !url.compare( urlSize - 4, 4, ".gif" ) + || !url.compare( urlSize - 4, 4, ".GIF" ) ) + { + internal = Internal::Adaptor::GifLoading::New( url, isLocalResource ); + } + } + if(urlSize >= 5){ // Avoid throwing out_of_range or failing silently if exceptions are turned-off on the compare(). (http://www.cplusplus.com/reference/string/string/compare/) + if( !url.compare( urlSize - 5, 5, ".webp" ) + || !url.compare( urlSize - 5, 5, ".WEBP" ) ) + { + internal = Internal::Adaptor::WebPLoading::New( url, isLocalResource ); + } + } + + return AnimatedImageLoading( internal.Get() ); +} + +AnimatedImageLoading AnimatedImageLoading::DownCast( BaseHandle handle ) +{ + return AnimatedImageLoading( dynamic_cast< Internal::Adaptor::AnimatedImageLoading* >( handle.GetObjectPtr() ) ); +} + +AnimatedImageLoading::~AnimatedImageLoading() +{ +} + +bool AnimatedImageLoading::LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector& pixelData ) +{ + return GetImplementation( *this ).LoadNextNFrames( frameStartIndex, count, pixelData ); +} + +ImageDimensions AnimatedImageLoading::GetImageSize() const +{ + return GetImplementation( *this ).GetImageSize(); +} + +uint32_t AnimatedImageLoading::GetImageCount() const +{ + return GetImplementation( *this ).GetImageCount(); +} + +uint32_t AnimatedImageLoading::GetFrameInterval( uint32_t frameIndex ) const +{ + return GetImplementation( *this ).GetFrameInterval( frameIndex ); +} + +AnimatedImageLoading::AnimatedImageLoading( Internal::Adaptor::AnimatedImageLoading* internal ) +: BaseHandle( internal ) +{ +} + +} // namespace Dali diff --git a/dali/devel-api/adaptor-framework/animated-image-loading.h b/dali/devel-api/adaptor-framework/animated-image-loading.h new file mode 100644 index 0000000..7c0a69b --- /dev/null +++ b/dali/devel-api/adaptor-framework/animated-image-loading.h @@ -0,0 +1,150 @@ +#ifndef DALI_ANIMATED_IMAGE_LOADING_H +#define DALI_ANIMATED_IMAGE_LOADING_H + +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +// EXTERNAL INCLUDES +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +class PixelData; +typedef Dali::Uint16Pair ImageDimensions; + +/** + * @addtogroup dali_adaptor_framework + * @{ + */ + +namespace Internal DALI_INTERNAL +{ +namespace Adaptor +{ +class AnimatedImageLoading; +} +} + +/** + * Class to manage loading frames of an animated image in small chunks. Lazy initializes only when + * data is actually needed. + * Note, once the Animated Image has loaded, the undecoded data will reside in memory until this object + * is released. (This is to speed up frame loads, which would otherwise have to re-acquire the + * data from disk) + */ +class DALI_ADAPTOR_API AnimatedImageLoading : public BaseHandle +{ +public: + + /** + * Create a GifLoading with the given url and resourceType. + * @param[in] url The url of the animated image to load + * @param[in] isLocalResource The true or false whether this is a local resource. + * @return A newly created GifLoading. + */ + static AnimatedImageLoading New( const std::string& url, bool isLocalResource ); + + /** + * @brief Constructor + */ + AnimatedImageLoading(); + + /** + * @brief Downcast an Object handle to Capture handle. + * + * If handle points to a Capture object the downcast produces valid + * handle. If not the returned handle is left uninitialized. + * + * @param[in] handle to An object. + * @return handle to a Capture object or an uninitialized handle. + */ + static AnimatedImageLoading DownCast( BaseHandle handle ); + + + /** + * @brief Copy constructor. + * + * @param[in] copy The AnimatedImageLoading to copy + */ + AnimatedImageLoading(const AnimatedImageLoading& copy) = default; + + /** + * @brief Assignment operator + * + * @param[in] rhs The AnimatedImageLoading to copy + * @return A reference to this + */ + AnimatedImageLoading& operator=(const AnimatedImageLoading& rhs) = default; + + /** + * @brief Destructor + */ + ~AnimatedImageLoading(); + + /** + * @brief Load the next N Frames of the animated image. + * + * @note This function will load the entire animated image into memory if not already loaded. + * @param[in] frameStartIndex The frame counter to start from. Will usually be the next frame + * after the previous invocation of this method, or 0 to start. + * @param[in] count The number of frames to load + * @param[out] pixelData The vector in which to return the frame data + * @return True if the frame data was successfully loaded + */ + bool LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector& pixelData ); + + /** + * @brief Get the size of a animated image. + * + * @return The width and height in pixels of the animated image. + */ + ImageDimensions GetImageSize() const; + + /** + * @brief Get the number of frames in this animated image. + */ + uint32_t GetImageCount() const; + + /** + * @brief Get the frame interval of the frame index + * + * @note The frame is needed to be loaded before this function is called. + * + * @return The time interval of the frame(microsecond). + */ + uint32_t GetFrameInterval( uint32_t frameIndex ) const; + +public: // Not intended for application developers + /// @cond internal + /** + * @brief This constructor is used by New() methods. + * + * @param[in] internal A pointer to a newly allocated Dali resource. + */ + explicit DALI_INTERNAL AnimatedImageLoading( Internal::Adaptor::AnimatedImageLoading* internal ); + /// @endcond +}; + +} // namespace Dali + +#endif // DALI_ANIMATED_IMAGE_LOADING_H diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list index b7e8f1f..789939d 100755 --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -2,6 +2,7 @@ SET( devel_api_src_files ${adaptor_devel_api_dir}/adaptor-framework/accessibility-adaptor.cpp + ${adaptor_devel_api_dir}/adaptor-framework/animated-image-loading.cpp ${adaptor_devel_api_dir}/adaptor-framework/application-devel.cpp ${adaptor_devel_api_dir}/adaptor-framework/bitmap-saver.cpp ${adaptor_devel_api_dir}/adaptor-framework/clipboard.cpp @@ -14,7 +15,6 @@ SET( devel_api_src_files ${adaptor_devel_api_dir}/adaptor-framework/file-loader.cpp ${adaptor_devel_api_dir}/adaptor-framework/file-stream.cpp ${adaptor_devel_api_dir}/adaptor-framework/image-loading.cpp - ${adaptor_devel_api_dir}/adaptor-framework/gif-loading.cpp ${adaptor_devel_api_dir}/adaptor-framework/input-method-context.cpp ${adaptor_devel_api_dir}/adaptor-framework/input-method-options.cpp ${adaptor_devel_api_dir}/adaptor-framework/native-image-source-devel.cpp @@ -42,6 +42,7 @@ SET( devel_api_adaptor_framework_header_files ${adaptor_devel_api_dir}/adaptor-framework/accessibility-action-handler.h ${adaptor_devel_api_dir}/adaptor-framework/accessibility-gesture-handler.h ${adaptor_devel_api_dir}/adaptor-framework/accessibility-gesture-event.h + ${adaptor_devel_api_dir}/adaptor-framework/animated-image-loading.h ${adaptor_devel_api_dir}/adaptor-framework/application-devel.h ${adaptor_devel_api_dir}/adaptor-framework/atspi-accessibility.h ${adaptor_devel_api_dir}/adaptor-framework/bitmap-saver.h @@ -59,7 +60,6 @@ SET( devel_api_adaptor_framework_header_files ${adaptor_devel_api_dir}/adaptor-framework/image-loader-input.h ${adaptor_devel_api_dir}/adaptor-framework/image-loader-plugin.h ${adaptor_devel_api_dir}/adaptor-framework/image-loading.h - ${adaptor_devel_api_dir}/adaptor-framework/gif-loading.h ${adaptor_devel_api_dir}/adaptor-framework/input-method-context.h ${adaptor_devel_api_dir}/adaptor-framework/input-method-options.h ${adaptor_devel_api_dir}/adaptor-framework/keyboard.h diff --git a/dali/internal/imaging/common/animated-image-loading-impl.h b/dali/internal/imaging/common/animated-image-loading-impl.h new file mode 100644 index 0000000..759eb09 --- /dev/null +++ b/dali/internal/imaging/common/animated-image-loading-impl.h @@ -0,0 +1,118 @@ +#ifndef DALI_INTERNAL_ANIMATED_IMAGE_LOADING_IMPL_H +#define DALI_INTERNAL_ANIMATED_IMAGE_LOADING_IMPL_H + +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +class PixelData; +typedef Dali::Uint16Pair ImageDimensions; + +namespace Internal +{ + +namespace Adaptor +{ + +class AnimatedImageLoading; +typedef IntrusivePtr AnimatedImageLoadingPtr; + +/** + * Class interface for animated image loading. + * Each loading classes for animated image file format(e.g., gif and webp) needs to inherit this interface + */ +class AnimatedImageLoading : public BaseObject +{ +public: + + /** + * @copydoc Dali::AnimatedImageLoading::New() + */ + static AnimatedImageLoadingPtr New( const std::string& url, bool isLocalResource ); + + AnimatedImageLoading() = default; + + // Moveable but not copyable + AnimatedImageLoading( const AnimatedImageLoading& ); + AnimatedImageLoading& operator=( const AnimatedImageLoading& ); + AnimatedImageLoading( AnimatedImageLoading&& ) = default; + AnimatedImageLoading& operator=( AnimatedImageLoading&& ) = default; + + /** + * @brief Destructor + */ + virtual ~AnimatedImageLoading() = default; + + /** + * @copydoc Dali::AnimatedImageLoading::LoadNextNFrames() + */ + virtual bool LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector& pixelData ) = 0; + + /** + * @copydoc Dali::AnimatedImageLoading::GetImageSize() + */ + virtual ImageDimensions GetImageSize() const = 0; + + /** + * @copydoc Dali::AnimatedImageLoading::GetImageCount() + */ + virtual uint32_t GetImageCount() const = 0; + + /** + * @copydoc Dali::AnimatedImageLoading::LoadFrameDelays() + */ + virtual uint32_t GetFrameInterval( uint32_t frameIndex ) const = 0; +}; + +} // namespace Adaptor + +} // namespace Internal + +// Helpers for api forwarding methods + +inline Internal::Adaptor::AnimatedImageLoading& GetImplementation( Dali::AnimatedImageLoading& handle) +{ + DALI_ASSERT_ALWAYS( handle && "AnimatedImageLoading handle is empty" ); + + BaseObject& object = handle.GetBaseObject(); + + return static_cast< Internal::Adaptor::AnimatedImageLoading& >( object ); +} + +inline const Internal::Adaptor::AnimatedImageLoading& GetImplementation( const Dali::AnimatedImageLoading& handle ) +{ + DALI_ASSERT_ALWAYS( handle && "AnimatedImageLoading handle is empty" ); + + const BaseObject& object = handle.GetBaseObject(); + + return static_cast< const Internal::Adaptor::AnimatedImageLoading& >( object ); +} + +} // namespace Dali + +#endif // DALI_INTERNAL_ANIMATED_IMAGE_LOADING_IMPL_H diff --git a/dali/devel-api/adaptor-framework/gif-loading.cpp b/dali/internal/imaging/common/gif-loading.cpp old mode 100755 new mode 100644 similarity index 97% rename from dali/devel-api/adaptor-framework/gif-loading.cpp rename to dali/internal/imaging/common/gif-loading.cpp index e49fbc8..187d91c --- a/dali/devel-api/adaptor-framework/gif-loading.cpp +++ b/dali/internal/imaging/common/gif-loading.cpp @@ -1,5 +1,5 @@ /* - * 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,7 @@ */ // CLASS HEADER -#include +#include // EXTERNAL INCLUDES #include @@ -45,6 +45,12 @@ namespace Dali { +namespace Internal +{ + +namespace Adaptor +{ + namespace { #if defined(DEBUG_ENABLED) @@ -1232,9 +1238,9 @@ public: ImageProperties imageProperties; }; -std::unique_ptr GifLoading::New( const std::string &url, bool isLocalResource ) +AnimatedImageLoadingPtr GifLoading::New( const std::string &url, bool isLocalResource ) { - return std::unique_ptr( new GifLoading( url, isLocalResource ) ); + return AnimatedImageLoadingPtr( new GifLoading( url, isLocalResource ) ); } GifLoading::GifLoading( const std::string &url, bool isLocalResource ) @@ -1248,7 +1254,7 @@ GifLoading::~GifLoading() delete mImpl; } -bool GifLoading::LoadNextNFrames( int frameStartIndex, int count, std::vector &pixelData ) +bool GifLoading::LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector &pixelData ) { int error; bool ret = false; @@ -1278,36 +1284,23 @@ bool GifLoading::LoadNextNFrames( int frameStartIndex, int count, std::vector &pixelData, Dali::Vector &frameDelays ) -{ - if( LoadFrameDelays( frameDelays ) ) - { - return LoadNextNFrames( 0, mImpl->loaderInfo.animated.frameCount, pixelData ); - } - return false; -} - -ImageDimensions GifLoading::GetImageSize() +ImageDimensions GifLoading::GetImageSize() const { return ImageDimensions( mImpl->imageProperties.w, mImpl->imageProperties.h ); } -int GifLoading::GetImageCount() +uint32_t GifLoading::GetImageCount() const { return mImpl->loaderInfo.animated.frameCount; } -bool GifLoading::LoadFrameDelays( Dali::Vector &frameDelays ) +uint32_t GifLoading::GetFrameInterval( uint32_t frameIndex ) const { - frameDelays.Clear(); + return mImpl->loaderInfo.animated.frames[frameIndex].info.delay * 10; +} - for( auto &&elem : mImpl->loaderInfo.animated.frames ) - { - // Read frame delay time, multiply 10 to change time unit to milliseconds - frameDelays.PushBack( elem.info.delay * 10 ); - } +} // namespace Adaptor - return true; -} +} // namespace Internal -} // namespace Dali +} // namespace Dali \ No newline at end of file diff --git a/dali/devel-api/adaptor-framework/gif-loading.h b/dali/internal/imaging/common/gif-loading.h old mode 100755 new mode 100644 similarity index 62% rename from dali/devel-api/adaptor-framework/gif-loading.h rename to dali/internal/imaging/common/gif-loading.h index 6143f15..4ee7565 --- a/dali/devel-api/adaptor-framework/gif-loading.h +++ b/dali/internal/imaging/common/gif-loading.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_GIF_LOADING_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. @@ -27,11 +27,16 @@ // INTERNAL INCLUDES #include +#include namespace Dali { -class PixelData; -typedef Dali::Uint16Pair ImageDimensions; + +namespace Internal +{ + +namespace Adaptor +{ /** * Class to manage loading frames of an animated gif in small chunks. Lazy initializes only when @@ -40,7 +45,7 @@ typedef Dali::Uint16Pair ImageDimensions; * is released. (This is to speed up frame loads, which would otherwise have to re-acquire the * data from disk) */ -class DALI_ADAPTOR_API GifLoading +class GifLoading: public Internal::Adaptor::AnimatedImageLoading { public: @@ -50,7 +55,7 @@ public: * @param[in] isLocalResource The true or false whether this is a local resource. * @return A newly created GifLoading. */ - static std::unique_ptr New( const std::string& url, bool isLocalResource ); + static AnimatedImageLoadingPtr New( const std::string& url, bool isLocalResource ); /** * @brief Constructor @@ -61,17 +66,10 @@ public: */ GifLoading( const std::string& url, bool isLocalResource ); - // Moveable but not copyable - - GifLoading( const GifLoading& ) = delete; - GifLoading& operator=( const GifLoading& ) = delete; - GifLoading( GifLoading&& ) = default; - GifLoading& operator=( GifLoading&& ) = default; - /** * @brief Destructor */ - ~GifLoading(); + ~GifLoading() override; /** * @brief Load the next N Frames of the gif. @@ -83,50 +81,38 @@ public: * @param[out] pixelData The vector in which to return the frame data * @return True if the frame data was successfully loaded */ - bool LoadNextNFrames( int frameStartIndex, int count, std::vector& pixelData ); - - /** - * @brief Load all frames of an animated gif file. - * - * @note This function will load the entire gif into memory if not already loaded. - * - * @param[out] pixelData The loaded pixel data for each frame. - * @param[out] frameDelays The loaded delay time for each frame. - * - * @return True if the loading succeeded, false otherwise. - */ - bool LoadAllFrames( std::vector& pixelData, Dali::Vector& frameDelays ); + bool LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector& pixelData ) override; /** * @brief Get the size of a gif image. * - * @note This function will load the entire gif into memory if not already loaded. - * * @return The width and height in pixels of the gif image. */ - ImageDimensions GetImageSize(); + ImageDimensions GetImageSize() const override; /** * @brief Get the number of frames in this gif. - * - * @note This function will load the entire gif into memory if not already loaded. */ - int GetImageCount(); + uint32_t GetImageCount() const override; /** - * @brief Load the frame delay counts into the provided array. + * @brief Get the frame interval of the frame index * - * @note This function will load the entire gif into memory if not already loaded. - * @param[in] frameDelays a vector to write the frame delays into - * @return true if the frame delays were successfully loaded + * @note The frame is needed to be loaded before this function is called. + * + * @return The time interval of the frame(microsecond). */ - bool LoadFrameDelays( Dali::Vector& frameDelays ); + uint32_t GetFrameInterval( uint32_t frameIndex ) const override; private: struct Impl; Impl* mImpl; }; +} // namespace Adaptor + +} // namespace Internal + } // namespace Dali #endif // DALI_INTERNAL_GIF_LOADING_H diff --git a/dali/internal/imaging/common/webp-loading.cpp b/dali/internal/imaging/common/webp-loading.cpp new file mode 100644 index 0000000..78e2e11 --- /dev/null +++ b/dali/internal/imaging/common/webp-loading.cpp @@ -0,0 +1,297 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +typedef unsigned char WebPByteType; + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ + +namespace +{ + +#if defined(DEBUG_ENABLED) +Debug::Filter *gWebPLoadingLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_GIF_LOADING" ); +#endif + +constexpr size_t MAXIMUM_DOWNLOAD_IMAGE_SIZE = 50 * 1024 * 1024; + +} + +struct WebPLoading::Impl +{ +public: + Impl( const std::string& url, bool isLocalResource ) + : mUrl( url ), + mLoadingFrame( 0 ) + { +#if WEBP_DEMUX_ABI_VERSION > 0x0101 + if( ReadWebPInformation( isLocalResource ) ) + { + WebPAnimDecoderOptions webPAnimDecoderOptions; + WebPAnimDecoderOptionsInit( &webPAnimDecoderOptions ); + webPAnimDecoderOptions.color_mode = MODE_RGBA; + mWebPAnimDecoder = WebPAnimDecoderNew( &mWebPData, &webPAnimDecoderOptions ); + WebPAnimDecoderGetInfo( mWebPAnimDecoder, &mWebPAnimInfo ); + mTimeStamp.assign( mWebPAnimInfo.frame_count, 0 ); + } +#endif + } + + bool ReadWebPInformation( bool isLocalResource ) + { +#if WEBP_DEMUX_ABI_VERSION > 0x0101 + WebPDataInit( &mWebPData ); + if( isLocalResource ) + { + Internal::Platform::FileReader fileReader( mUrl ); + FILE *fp = fileReader.GetFile(); + if( fp == NULL ) + { + return false; + } + + if( fseek( fp, 0, SEEK_END ) <= -1 ) + { + return false; + } + + mWebPData.size = ftell( fp ); + if( ( ! fseek( fp, 0, SEEK_SET ) ) ) + { + unsigned char *WebPDataBuffer; + WebPDataBuffer = reinterpret_cast( malloc(sizeof( WebPByteType ) * mWebPData.size ) ); + mWebPData.size = fread( WebPDataBuffer, sizeof( WebPByteType ), mWebPData.size, fp ); + mWebPData.bytes = WebPDataBuffer; + } + else + { + return false; + } + } + else + { + // remote file + bool succeeded; + Dali::Vector dataBuffer; + size_t dataSize; + + succeeded = TizenPlatform::Network::DownloadRemoteFileIntoMemory( mUrl, dataBuffer, dataSize, MAXIMUM_DOWNLOAD_IMAGE_SIZE ); + if( succeeded ) + { + size_t blobSize = dataBuffer.Size(); + if( blobSize > 0U ) + { + // Open a file handle on the memory buffer: + Dali::Internal::Platform::FileReader fileReader( dataBuffer, blobSize ); + FILE * const fp = fileReader.GetFile(); + if ( NULL != fp ) + { + if( ( ! fseek( fp, 0, SEEK_SET ) ) ) + { + unsigned char *WebPDataBuffer; + WebPDataBuffer = reinterpret_cast( malloc(sizeof( WebPByteType ) * blobSize ) ); + mWebPData.size = fread( WebPDataBuffer, sizeof( WebPByteType ), mWebPData.size, fp ); + mWebPData.bytes = WebPDataBuffer; + } + else + { + DALI_LOG_ERROR( "Error seeking within file\n" ); + } + } + else + { + DALI_LOG_ERROR( "Error reading file\n" ); + } + } + } + } + return true; +#else + return false; +#endif + } + + // Moveable but not copyable + + Impl( const Impl& ) = delete; + Impl& operator=( const Impl& ) = delete; + Impl( Impl&& ) = default; + Impl& operator=( Impl&& ) = default; + + ~Impl() + { +#if WEBP_DEMUX_ABI_VERSION > 0x0101 + if( &mWebPData != NULL ) + { + free( (void*)mWebPData.bytes ); + mWebPData.bytes = nullptr; + WebPDataInit( &mWebPData ); + } + if( mWebPAnimDecoder ) + { + WebPAnimDecoderDelete(mWebPAnimDecoder); + } +#endif + } + + std::string mUrl; + std::vector mTimeStamp; + uint32_t mLoadingFrame; + +#if WEBP_DEMUX_ABI_VERSION > 0x0101 + WebPData mWebPData; + WebPAnimDecoder* mWebPAnimDecoder; + WebPAnimInfo mWebPAnimInfo; +#endif +}; + +AnimatedImageLoadingPtr WebPLoading::New( const std::string &url, bool isLocalResource ) +{ +#if WEBP_DEMUX_ABI_VERSION <= 0x0101 + DALI_LOG_ERROR( "The system do not support Animated WebP format.\n" ); +#endif + return AnimatedImageLoadingPtr( new WebPLoading( url, isLocalResource ) ); +} + +WebPLoading::WebPLoading( const std::string &url, bool isLocalResource ) +: mImpl( new WebPLoading::Impl( url, isLocalResource ) ) +{ +} + +WebPLoading::~WebPLoading() +{ + delete mImpl; +} + +bool WebPLoading::LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector &pixelData ) +{ +#if WEBP_DEMUX_ABI_VERSION > 0x0101 + if( frameStartIndex >= mImpl->mWebPAnimInfo.frame_count ) + { + return false; + } + + DALI_LOG_INFO( gWebPLoadingLogFilter, Debug::Concise, "LoadNextNFrames( frameStartIndex:%d, count:%d )\n", frameStartIndex, count ); + + if( mImpl->mLoadingFrame > frameStartIndex ) + { + mImpl->mLoadingFrame = 0; + WebPAnimDecoderReset( mImpl->mWebPAnimDecoder ); + } + + for( ; mImpl->mLoadingFrame < frameStartIndex ; ++mImpl->mLoadingFrame ) + { + uint8_t* frameBuffer; + int timestamp; + WebPAnimDecoderGetNext( mImpl->mWebPAnimDecoder, &frameBuffer, ×tamp ); + mImpl->mTimeStamp[mImpl->mLoadingFrame] = timestamp; + } + + for( int i = 0; i < count; ++i ) + { + const int bufferSize = mImpl->mWebPAnimInfo.canvas_width * mImpl->mWebPAnimInfo.canvas_height * sizeof( uint32_t ); + uint8_t* frameBuffer; + int timestamp; + WebPAnimDecoderGetNext( mImpl->mWebPAnimDecoder, &frameBuffer, ×tamp ); + + auto pixelBuffer = new uint8_t[ bufferSize ]; + memcpy( pixelBuffer, frameBuffer, bufferSize ); + mImpl->mTimeStamp[mImpl->mLoadingFrame] = timestamp; + + if( pixelBuffer ) + { + pixelData.push_back( Dali::PixelData::New( pixelBuffer, bufferSize, + mImpl->mWebPAnimInfo.canvas_width, mImpl->mWebPAnimInfo.canvas_height, + Dali::Pixel::RGBA8888, Dali::PixelData::DELETE_ARRAY) ); + } + + mImpl->mLoadingFrame++; + if( mImpl->mLoadingFrame >= mImpl->mWebPAnimInfo.frame_count ) + { + mImpl->mLoadingFrame = 0; + WebPAnimDecoderReset( mImpl->mWebPAnimDecoder ); + } + } + + return true; +#else + return false; +#endif +} + +ImageDimensions WebPLoading::GetImageSize() const +{ +#if WEBP_DEMUX_ABI_VERSION > 0x0101 + return ImageDimensions( mImpl->mWebPAnimInfo.canvas_width, mImpl->mWebPAnimInfo.canvas_height ); +#else + return ImageDimensions(); +#endif +} + +uint32_t WebPLoading::GetImageCount() const +{ +#if WEBP_DEMUX_ABI_VERSION > 0x0101 + return mImpl->mWebPAnimInfo.frame_count; +#else + return 0u; +#endif +} + +uint32_t WebPLoading::GetFrameInterval( uint32_t frameIndex ) const +{ + if( frameIndex >= GetImageCount() ) + { + return 0u; + } + else + { + if( frameIndex > 0 ) + { + return mImpl->mTimeStamp[frameIndex] - mImpl->mTimeStamp[frameIndex - 1]; + } + return mImpl->mTimeStamp[frameIndex]; + } +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali \ No newline at end of file diff --git a/dali/internal/imaging/common/webp-loading.h b/dali/internal/imaging/common/webp-loading.h new file mode 100644 index 0000000..01bd4e3 --- /dev/null +++ b/dali/internal/imaging/common/webp-loading.h @@ -0,0 +1,121 @@ +#ifndef DALI_INTERNAL_WEBP_LOADING_H +#define DALI_INTERNAL_WEBP_LOADING_H + +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali +{ +class PixelData; +typedef Dali::Uint16Pair ImageDimensions; + +namespace Internal +{ + +namespace Adaptor +{ + +/** + * Class to manage loading frames of an animated webp in small chunks. Lazy initializes only when + * data is actually needed. + * Note, once the WEBP has loaded, the undecoded data will reside in memory until this object + * is released. (This is to speed up frame loads, which would otherwise have to re-acquire the + * data from disk) + */ +class WebPLoading: public Internal::Adaptor::AnimatedImageLoading +{ +public: + + /** + * Create a WebPLoading with the given url and resourceType. + * @param[in] url The url of the webp image to load + * @param[in] isLocalResource The true or false whether this is a local resource. + * @return A newly created WebPLoading. + */ + static AnimatedImageLoadingPtr New( const std::string& url, bool isLocalResource ); + + /** + * @brief Constructor + * + * Construct a Loader with the given URL + * @param[in] url The url of the webp image to load + * @param[in] isLocalResource The true or false whether this is a local resource. + */ + WebPLoading( const std::string& url, bool isLocalResource ); + + + /** + * @brief Destructor + */ + ~WebPLoading() override; + + /** + * @brief Load the next N Frames of the webp. + * + * @note This function will load the entire webp into memory if not already loaded. + * @param[in] frameStartIndex The frame counter to start from. Will usually be the next frame + * after the previous invocation of this method, or 0 to start. + * @param[in] count The number of frames to load + * @param[out] pixelData The vector in which to return the frame data + * @return True if the frame data was successfully loaded + */ + bool LoadNextNFrames( uint32_t frameStartIndex, int count, std::vector& pixelData ) override; + + /** + * @brief Get the size of a webp image. + * + * @return The width and height in pixels of the webp image. + */ + ImageDimensions GetImageSize() const override; + + /** + * @brief Get the number of frames in this webp. + */ + uint32_t GetImageCount() const override; + + /** + * @brief Get the frame interval of the frame index + * + * @note The frame is needed to be loaded before this function is called. + * + * @return The time interval of the frame(microsecond). + */ + uint32_t GetFrameInterval( uint32_t frameIndex ) const override; + +private: + struct Impl; + Impl* mImpl; +}; + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali + +#endif // DALI_INTERNAL_WEBP_LOADING_H diff --git a/dali/internal/imaging/file.list b/dali/internal/imaging/file.list index 6558e96..c91ffcf 100644 --- a/dali/internal/imaging/file.list +++ b/dali/internal/imaging/file.list @@ -18,6 +18,8 @@ SET( adaptor_imaging_common_src_files ${adaptor_imaging_dir}/common/loader-png.cpp ${adaptor_imaging_dir}/common/loader-wbmp.cpp ${adaptor_imaging_dir}/common/pixel-manipulation.cpp + ${adaptor_imaging_dir}/common/gif-loading.cpp + ${adaptor_imaging_dir}/common/webp-loading.cpp ) # module: imaging, backend: tizen diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index 0e7a469..6d7bafc 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -56,6 +56,10 @@ BuildRequires: pkgconfig BuildRequires: gawk BuildRequires: cmake BuildRequires: giflib-devel +BuildRequires: pkgconfig(libwebp) +BuildRequires: pkgconfig(libwebpdecoder) +BuildRequires: pkgconfig(libwebpdemux) +BuildRequires: pkgconfig(libwebpmux) BuildRequires: pkgconfig(fontconfig) BuildRequires: libjpeg-turbo-devel BuildRequires: pkgconfig(vconf) -- 2.7.4 From b2b2447230b78d870dba9e11961a01fa9b03a09c Mon Sep 17 00:00:00 2001 From: Victor Cebollada Date: Mon, 22 Jun 2020 15:02:23 +0100 Subject: [PATCH 15/16] Fixed MS Windows min, max compile error. Change-Id: I96d60fce295aae527313c24dd480b069466b21b3 Signed-off-by: Victor Cebollada --- dali/internal/graphics/common/egl-include.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dali/internal/graphics/common/egl-include.h b/dali/internal/graphics/common/egl-include.h index d0d1cad..6e744cf 100644 --- a/dali/internal/graphics/common/egl-include.h +++ b/dali/internal/graphics/common/egl-include.h @@ -16,6 +16,9 @@ #undef CopyMemory #undef CreateWindow +#undef min +#undef max + #include #endif // EGL_INCLUDE_H -- 2.7.4 From 9ab2b37e3e110c1bee6c429e90a58e42eece6c8a Mon Sep 17 00:00:00 2001 From: "Seungho, Baek" Date: Thu, 2 Jul 2020 10:51:45 +0900 Subject: [PATCH 16/16] Add comment in the capture.h - Add @return comment at the GetNativeImageSource() Change-Id: Ic46eac21b4f138871ae5e1a7b9dc19140da85b9e Signed-off-by: Seungho, Baek --- dali/public-api/capture/capture.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dali/public-api/capture/capture.h b/dali/public-api/capture/capture.h index 29ee5b5..d27865b 100755 --- a/dali/public-api/capture/capture.h +++ b/dali/public-api/capture/capture.h @@ -176,6 +176,7 @@ public: * @param[in] source source actor to be used for capture. * @param[in] size captured size. * @param[in] path image file path to be saved as a file. + * If path is empty string, the captured result is not be saved as a file. * @param[in] clearColor background color of captured scene * @param[in] quality The value to control image quality for jpeg file format in the range [1, 100] */ @@ -189,6 +190,7 @@ public: * @param[in] source source actor to be used for capture. * @param[in] size captured size. * @param[in] path image file path to be saved as a file. + * If path is empty string, the captured result is not be saved as a file. * @param[in] clearColor background color of captured scene */ void Start( Actor source, const Vector2& size, const std::string &path, const Vector4& clearColor ); @@ -201,6 +203,7 @@ public: * @param[in] source source actor to be used for capture. * @param[in] size captured size. * @param[in] path image file path to be saved as a file. + * If path is empty string, the captured result is not be saved as a file. * @note Clear color is transparent. */ void Start( Actor source, const Vector2& size, const std::string &path ); @@ -209,6 +212,8 @@ public: * @brief Get NativeImageSourcePtr that is saved captured image. * * @SINCE_1_5.10 + * + * @return NativeImageSourcePtr Captured result that can be rendered with DALi */ Dali::NativeImageSourcePtr GetNativeImageSource() const; -- 2.7.4