From: Richard Huang Date: Tue, 27 Nov 2018 15:16:38 +0000 (+0000) Subject: Support multiple window rendering X-Git-Tag: submit/tizen/20190225.081322~1^2^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d8944bba8449a3c5bce03041eccccf2eba4a7ae3;p=platform%2Fcore%2Fuifw%2Fdali-core.git Support multiple window rendering Multiple windows support is added to Core with new Scene API. It also removed the top margin from the Stage as system overlay is already removed. Change-Id: If6b42be996cf884be6da00c41456155a881fc554 --- diff --git a/automated-tests/src/dali-internal/CMakeLists.txt b/automated-tests/src/dali-internal/CMakeLists.txt index 64b34e720..2566323cd 100644 --- a/automated-tests/src/dali-internal/CMakeLists.txt +++ b/automated-tests/src/dali-internal/CMakeLists.txt @@ -26,6 +26,7 @@ LIST(APPEND TC_SOURCES ../dali/dali-test-suite-utils/test-native-image.cpp ../dali/dali-test-suite-utils/test-platform-abstraction.cpp ../dali/dali-test-suite-utils/test-render-controller.cpp + ../dali/dali-test-suite-utils/test-render-surface.cpp ../dali/dali-test-suite-utils/test-trace-call-stack.cpp ) diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-Core.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-Core.cpp index e12a27a81..99c55b8c6 100644 --- a/automated-tests/src/dali-internal/utc-Dali-Internal-Core.cpp +++ b/automated-tests/src/dali-internal/utc-Dali-Internal-Core.cpp @@ -66,35 +66,6 @@ public: } // anonymous namespace -int UtcDaliCoreTopMargin(void) -{ - TestApplication application; - tet_infoline("Testing Dali::Integration::Core::SetTopMargin"); - - Stage stage = Stage::GetCurrent(); - - // Test Stage size without top-margin - - const unsigned int initialWidth( stage.GetSize().width ); - const unsigned int initialHeight( stage.GetSize().height ); - - DALI_TEST_EQUALS( TestApplication::DEFAULT_SURFACE_WIDTH, initialWidth, TEST_LOCATION ); - DALI_TEST_EQUALS( TestApplication::DEFAULT_SURFACE_HEIGHT, initialHeight, TEST_LOCATION ); - - // Retest with top-margin - - unsigned int margin( 10 ); - application.SetTopMargin( margin ); - - const unsigned int newWidth( stage.GetSize().width ); - const unsigned int newHeight( stage.GetSize().height ); - - DALI_TEST_EQUALS( TestApplication::DEFAULT_SURFACE_WIDTH, newWidth, TEST_LOCATION ); - DALI_TEST_EQUALS( (TestApplication::DEFAULT_SURFACE_HEIGHT - margin), newHeight, TEST_LOCATION ); - - END_TEST; -} - int UtcDaliCoreProcessEvents(void) { TestApplication application; diff --git a/automated-tests/src/dali/CMakeLists.txt b/automated-tests/src/dali/CMakeLists.txt index 288073dcc..62bad228a 100644 --- a/automated-tests/src/dali/CMakeLists.txt +++ b/automated-tests/src/dali/CMakeLists.txt @@ -77,6 +77,7 @@ SET(TC_SOURCES utc-Dali-RenderTaskList.cpp utc-Dali-ResourceImage.cpp utc-Dali-Sampler.cpp + utc-Dali-Scene.cpp utc-Dali-Scripting.cpp utc-Dali-Shader.cpp utc-Dali-SignalDelegate.cpp @@ -115,6 +116,7 @@ LIST(APPEND TC_SOURCES dali-test-suite-utils/test-native-image.cpp dali-test-suite-utils/test-platform-abstraction.cpp dali-test-suite-utils/test-render-controller.cpp + dali-test-suite-utils/test-render-surface.cpp dali-test-suite-utils/test-trace-call-stack.cpp ) diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp index c953f50d0..1562d27d1 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -54,8 +54,6 @@ void TestApplication::Initialize() Integration::StencilBufferAvailable::TRUE ); mCore->ContextCreated(); - mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight ); - mCore->SetDpi( mDpi.x, mDpi.y ); Dali::Integration::Log::LogFunction logFunction(&TestApplication::LogMessage); Dali::Integration::Log::InstallLogFunction(logFunction); @@ -65,12 +63,22 @@ void TestApplication::Initialize() Dali::Integration::Trace::LogContext( true, "Test" ); + mRenderSurface = new TestRenderSurface( Dali::PositionSize( 0, 0, mSurfaceWidth, mSurfaceHeight ) ); + mScene = Dali::Integration::Scene::New( Vector2( static_cast( mSurfaceWidth ), static_cast( mSurfaceHeight ) ) ); + mScene.SetSurface( *mRenderSurface ); + + mScene.SetDpi( Vector2( static_cast( mDpi.x ), static_cast( mDpi.y ) ) ); + + mCore->SurfaceResized( mRenderSurface ); + mCore->SceneCreated(); + mCore->Initialize(); } TestApplication::~TestApplication() { Dali::Integration::Log::UninstallLogFunction(); + delete mRenderSurface; delete mCore; } @@ -149,19 +157,6 @@ void TestApplication::SendNotification() mCore->ProcessEvents(); } -void TestApplication::SetSurfaceWidth( uint32_t width, uint32_t height ) -{ - mSurfaceWidth = width; - mSurfaceHeight = height; - - mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight ); -} - -void TestApplication::SetTopMargin( uint32_t margin ) -{ - mCore->SetTopMargin( margin ); -} - void TestApplication::DoUpdate( uint32_t intervalMilliseconds, const char* location ) { if( GetUpdateStatus() == 0 && diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-application.h b/automated-tests/src/dali/dali-test-suite-utils/test-application.h index d1e042d3e..fc2929cd7 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-application.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-application.h @@ -2,7 +2,7 @@ #define __DALI_TEST_APPLICATION_H__ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -24,9 +24,11 @@ #include "test-gl-sync-abstraction.h" #include "test-gl-abstraction.h" #include "test-render-controller.h" +#include "test-render-surface.h" #include #include #include +#include namespace Dali { @@ -69,8 +71,6 @@ public: TestGestureManager& GetGestureManager(); void ProcessEvent(const Integration::Event& event); void SendNotification(); - void SetSurfaceWidth( uint32_t width, unsigned height ); - void SetTopMargin( uint32_t margin ); bool Render( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL, const char* location=NULL ); uint32_t GetUpdateStatus(); bool UpdateOnly( uint32_t intervalMilliseconds = DEFAULT_RENDER_INTERVAL ); @@ -83,6 +83,11 @@ public: mLoggingEnabled = enabled; } + Integration::Scene GetScene() const + { + return mScene; + } + private: void DoUpdate( uint32_t intervalMilliseconds, const char* location=NULL ); @@ -92,11 +97,13 @@ protected: TestGlAbstraction mGlAbstraction; TestGlSyncAbstraction mGlSyncAbstraction; TestGestureManager mGestureManager; + TestRenderSurface* mRenderSurface; Integration::UpdateStatus mStatus; Integration::RenderStatus mRenderStatus; Integration::Core* mCore; + Dali::Integration::Scene mScene; uint32_t mSurfaceWidth; uint32_t mSurfaceHeight; diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp new file mode 100644 index 000000000..332d77eb7 --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2019 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. + * + */ + +#include "test-render-surface.h" + +namespace Dali +{ + +TestRenderSurface::TestRenderSurface( Dali::PositionSize positionSize ) +: mPositionSize( positionSize ), + mBackgroundColor() +{ +} + +TestRenderSurface::~TestRenderSurface() +{ +} + +Dali::PositionSize TestRenderSurface::GetPositionSize() const +{ + return mPositionSize; +}; + +void TestRenderSurface::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) +{ + dpiHorizontal = dpiVertical = 96; +}; + +void TestRenderSurface::InitializeGraphics() +{ +} + +void TestRenderSurface::CreateSurface() +{ +} + +void TestRenderSurface::DestroySurface() +{ +} + +bool TestRenderSurface::ReplaceGraphicsSurface() +{ + return false; +} + +void TestRenderSurface::MoveResize( Dali::PositionSize positionSize ) +{ + mPositionSize = positionSize; +} + +void TestRenderSurface::StartRender() +{ +} + +bool TestRenderSurface::PreRender( bool resizingSurface ) +{ + return true; +} + +void TestRenderSurface::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ) +{ +} + +void TestRenderSurface::StopRender() +{ +} + +void TestRenderSurface::ReleaseLock() +{ +} + +Dali::Integration::RenderSurface::Type TestRenderSurface::GetSurfaceType() +{ + return WINDOW_RENDER_SURFACE; +} + +void TestRenderSurface::MakeContextCurrent() +{ +} + +Integration::DepthBufferAvailable TestRenderSurface::GetDepthBufferRequired() +{ + return Integration::DepthBufferAvailable::TRUE; +} + +Integration::StencilBufferAvailable TestRenderSurface::GetStencilBufferRequired() +{ + return Integration::StencilBufferAvailable::TRUE; +} + +void TestRenderSurface::SetBackgroundColor( Vector4 color ) +{ + mBackgroundColor = color; +} + +Vector4 TestRenderSurface::GetBackgroundColor() +{ + return mBackgroundColor; +} + +} // Namespace dali diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.h b/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.h new file mode 100644 index 000000000..fba89c25c --- /dev/null +++ b/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.h @@ -0,0 +1,155 @@ +#ifndef TEST_REENDER_SURFACE_H +#define TEST_REENDER_SURFACE_H + +/* + * Copyright (c) 2019 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 +{ + +/** + * Concrete implementation of the RenderSurface class. + */ +class DALI_CORE_API TestRenderSurface : public Dali::Integration::RenderSurface +{ +public: + + /** + * @copydoc Dali::Integration::RenderSurface::RenderSurface + */ + TestRenderSurface( Dali::PositionSize positionSize ); + + /** + * @copydoc Dali::Integration::RenderSurface::~RenderSurface + */ + virtual ~TestRenderSurface(); + + /** + * @copydoc Dali::Integration::RenderSurface::GetPositionSize + */ + virtual Dali::PositionSize GetPositionSize() const; + + /** + * @copydoc Dali::Integration::RenderSurface::GetDpi + */ + virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ); + + /** + * @copydoc Dali::Integration::RenderSurface::InitializeGraphics + */ + virtual void InitializeGraphics(); + + /** + * @copydoc Dali::Integration::RenderSurface::CreateSurface + */ + virtual void CreateSurface(); + + /** + * @copydoc Dali::Integration::RenderSurface::DestroySurface + */ + virtual void DestroySurface(); + + /** + * @copydoc Dali::Integration::RenderSurface::ReplaceGraphicsSurface + */ + virtual bool ReplaceGraphicsSurface(); + + /** + * @copydoc Dali::Integration::RenderSurface::MoveResize + */ + virtual void MoveResize( Dali::PositionSize positionSize ); + + /** + * @copydoc Dali::Integration::RenderSurface::StartRender + */ + virtual void StartRender(); + + /** + * @copydoc Dali::Integration::RenderSurface::PreRender + */ + virtual bool PreRender( bool resizingSurface ); + + /** + * @copydoc Dali::Integration::RenderSurface::PostRender + */ + virtual void PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface ); + + /** + * @copydoc Dali::Integration::RenderSurface::StopRender + */ + virtual void StopRender(); + + /** + * @copydoc Dali::Integration::RenderSurface::ReleaseLock + */ + virtual void ReleaseLock(); + + /** + * @copydoc Dali::Integration::RenderSurface::GetSurfaceType + */ + virtual Dali::Integration::RenderSurface::Type GetSurfaceType(); + + /** + * @copydoc Dali::Integration::RenderSurface::MakeContextCurrent + */ + virtual void MakeContextCurrent(); + + /** + * @copydoc Dali::Integration::RenderSurface::GetDepthBufferRequired + */ + virtual Integration::DepthBufferAvailable GetDepthBufferRequired(); + + /** + * @copydoc Dali::Integration::RenderSurface::GetStencilBufferRequired + */ + virtual Integration::StencilBufferAvailable GetStencilBufferRequired(); + + /** + * @copydoc Dali::Integration::RenderSurface::SetBackgroundColor + */ + virtual void SetBackgroundColor( Vector4 color ); + + /** + * @copydoc Dali::Integration::RenderSurface::GetBackgroundColor + */ + virtual Vector4 GetBackgroundColor(); + +private: + + /** + * @brief Undefined copy constructor. RenderSurface cannot be copied + */ + TestRenderSurface( const TestRenderSurface& rhs ); + + /** + * @brief Undefined assignment operator. RenderSurface cannot be copied + */ + TestRenderSurface& operator=( const TestRenderSurface& rhs ); + +private: + + Dali::PositionSize mPositionSize; + Vector4 mBackgroundColor; ///< The background color of the surface +}; + +} // Dali + +#endif diff --git a/automated-tests/src/dali/utc-Dali-CameraActor.cpp b/automated-tests/src/dali/utc-Dali-CameraActor.cpp index 415f6cfd8..ac726f74a 100644 --- a/automated-tests/src/dali/utc-Dali-CameraActor.cpp +++ b/automated-tests/src/dali/utc-Dali-CameraActor.cpp @@ -282,7 +282,7 @@ int UtcDaliCameraActorSetFieldOfViewP(void) CameraActor defaultCamera = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); const float defaultFieldOfView = defaultCamera.GetFieldOfView(); - CameraActor actor = CameraActor::New(); + CameraActor actor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); DALI_TEST_EQUALS( actor.GetFieldOfView(), defaultFieldOfView, TEST_LOCATION ); float fieldOfView = Math::PI / 3.0f; @@ -303,7 +303,7 @@ int UtcDaliCameraActorSetFieldOfViewN(void) CameraActor defaultCamera = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); const float defaultFieldOfView = defaultCamera.GetFieldOfView(); - CameraActor actor = CameraActor::New(); + CameraActor actor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); DALI_TEST_EQUALS( actor.GetFieldOfView(), defaultFieldOfView, TEST_LOCATION ); float fieldOfView = Math::PI / 3.0f; @@ -327,7 +327,7 @@ int UtcDaliCameraActorGetFieldOfViewP(void) const float cameraZ = 2.0f * std::max( size.width, size.height ); const float expectedFieldOfView = 2.0f * std::atan( size.height * 0.5f / cameraZ ); - CameraActor actor = CameraActor::New(); + CameraActor actor = CameraActor::New( size ); DALI_TEST_EQUALS( actor.GetFieldOfView(), expectedFieldOfView, TEST_LOCATION ); float value; @@ -364,7 +364,7 @@ int UtcDaliCameraActorSetAspectRatioP(void) TestApplication application; tet_infoline( "Testing Dali::CameraActor Set Aspect Ratio (P)" ); - CameraActor actor = CameraActor::New(); + CameraActor actor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); DALI_TEST_EQUALS( actor.GetAspectRatio(), static_cast( TestApplication::DEFAULT_SURFACE_WIDTH ) / static_cast( TestApplication::DEFAULT_SURFACE_HEIGHT ), TEST_LOCATION ); // Set an initial value to confirm a further set changes it. @@ -407,7 +407,7 @@ int UtcDaliCameraActorGetAspectRatioP(void) TestApplication application; tet_infoline("Testing Dali::CameraActor Get Aspect Ratio"); - CameraActor actor = CameraActor::New(); + CameraActor actor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); float defaultAspect = static_cast( TestApplication::DEFAULT_SURFACE_WIDTH ) / static_cast( TestApplication::DEFAULT_SURFACE_HEIGHT ); DALI_TEST_EQUALS( actor.GetAspectRatio(), defaultAspect, TEST_LOCATION ); @@ -576,7 +576,7 @@ int UtcDaliCameraActorGetFarClippingPlaneP(void) TestApplication application; tet_infoline( "Testing Dali::CameraActor Get Far clipping plane (P)" ); - CameraActor actor = CameraActor::New(); + CameraActor actor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); float defaultValue = 800.0f + ( 0xFFFF >> 4 ); DALI_TEST_EQUALS( actor.GetFarClippingPlane(), defaultValue, TEST_LOCATION ); @@ -805,16 +805,14 @@ int UtcDaliCameraActorSetPerspectiveProjectionN(void) TestApplication application; tet_infoline( "Testing Dali::CameraActor::SetPerspectiveProjection (N)" ); - Stage stage = Stage::GetCurrent(); - Vector2 stageSize = stage.GetSize(); - CameraActor actor = CameraActor::New(); - // Check that setting perspective projection without a size (using zero size) uses the stages size. + // Check that setting perspective projection without a size does not do anything. actor.SetPerspectiveProjection( Size::ZERO ); - float nearClippingPlane = std::max( stageSize.width, stageSize.height ); - float farClippingPlane = nearClippingPlane + static_cast( 0xFFFF >> 4 ); + // So the default values should be the same as defined in CameraActor + float nearClippingPlane = 800.0f; + float farClippingPlane = nearClippingPlane + 2.0f * nearClippingPlane; DALI_TEST_EQUALS( nearClippingPlane, actor.GetNearClippingPlane(), FLOAT_EPSILON, TEST_LOCATION ); DALI_TEST_EQUALS( farClippingPlane, actor.GetFarClippingPlane(), FLOAT_EPSILON, TEST_LOCATION ); diff --git a/automated-tests/src/dali/utc-Dali-RenderTask.cpp b/automated-tests/src/dali/utc-Dali-RenderTask.cpp index b784e1a7d..6c6197d8e 100644 --- a/automated-tests/src/dali/utc-Dali-RenderTask.cpp +++ b/automated-tests/src/dali/utc-Dali-RenderTask.cpp @@ -670,11 +670,16 @@ int UtcDaliRenderTaskSetExclusive(void) // Check that the actor1 was rendered const std::vector& boundTextures = application.GetGlAbstraction().GetBoundTextures( GL_TEXTURE0 ); - DALI_TEST_EQUALS( boundTextures.size(), 1u, TEST_LOCATION ); + DALI_TEST_GREATER( boundTextures.size(), static_cast::size_type>( 0 ), TEST_LOCATION ); if ( boundTextures.size() ) { - DALI_TEST_EQUALS( boundTextures[0], 8u/*unique to actor1*/, TEST_LOCATION ); + int c = 0; + DALI_TEST_EQUALS( boundTextures[c++], 8u/*unique to actor1*/, TEST_LOCATION ); + if( boundTextures.size() > 1 ) + { + DALI_TEST_EQUALS( boundTextures[c++], 8u/*unique to actor1*/, TEST_LOCATION ); + } } BufferImage img2 = BufferImage::New( 1,1 ); @@ -693,12 +698,17 @@ int UtcDaliRenderTaskSetExclusive(void) application.Render(); // Check that the actors were rendered - DALI_TEST_EQUALS( boundTextures.size(), 2u, TEST_LOCATION ); + DALI_TEST_GREATER( boundTextures.size(), static_cast::size_type>( 1 ), TEST_LOCATION ); if ( boundTextures.size() ) { - DALI_TEST_EQUALS( boundTextures[0], 9u/*unique to actor2*/, TEST_LOCATION ); - DALI_TEST_EQUALS( boundTextures[1], 8u/*unique to actor1*/, TEST_LOCATION ); + int c = 0; + DALI_TEST_EQUALS( boundTextures[c++], 9u/*unique to actor2*/, TEST_LOCATION ); + if( boundTextures.size() > 2 ) + { + DALI_TEST_EQUALS( boundTextures[c++], 9u/*unique to actor1*/, TEST_LOCATION ); + } + DALI_TEST_EQUALS( boundTextures[c++], 8u/*unique to actor1*/, TEST_LOCATION ); } BufferImage img3 = BufferImage::New( 1,1 ); @@ -717,13 +727,18 @@ int UtcDaliRenderTaskSetExclusive(void) application.Render(); // Check that the actors were rendered - DALI_TEST_EQUALS( boundTextures.size(), 3u, TEST_LOCATION ); + DALI_TEST_GREATER( boundTextures.size(), static_cast::size_type>( 2 ), TEST_LOCATION ); if ( boundTextures.size() ) { - DALI_TEST_EQUALS( boundTextures[0], 10u/*unique to actor3*/, TEST_LOCATION ); - DALI_TEST_EQUALS( boundTextures[1], 9u/*unique to actor2*/, TEST_LOCATION ); - DALI_TEST_EQUALS( boundTextures[2], 8u/*unique to actor1*/, TEST_LOCATION ); + int c = 0; + DALI_TEST_EQUALS( boundTextures[c++], 10u/*unique to actor3*/, TEST_LOCATION ); + if( boundTextures.size() > 3 ) + { + DALI_TEST_EQUALS( boundTextures[c++], 10u/*unique to actor2*/, TEST_LOCATION ); + } + DALI_TEST_EQUALS( boundTextures[c++], 9u/*unique to actor2*/, TEST_LOCATION ); + DALI_TEST_EQUALS( boundTextures[c++], 8u/*unique to actor1*/, TEST_LOCATION ); } // Both actors are now connected to the root node @@ -1139,9 +1154,9 @@ int UtcDaliRenderTaskGetFrameBufferN(void) RenderTask task = taskList.GetTask( 0u ); - // By default render-tasks do not render off-screen + // A scene creates frame buffer by default FrameBuffer frameBuffer = task.GetFrameBuffer(); - DALI_TEST_CHECK( !frameBuffer ); + DALI_TEST_CHECK( frameBuffer ); END_TEST; } @@ -1914,7 +1929,7 @@ int UtcDaliRenderTaskContinuous01(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Actor secondRootActor = CreateRenderableActorSuccess(application, "aFile.jpg"); @@ -1952,7 +1967,7 @@ int UtcDaliRenderTaskContinuous02(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Actor secondRootActor = CreateRenderableActorSuccess(application, "aFile.jpg"); @@ -1992,7 +2007,7 @@ int UtcDaliRenderTaskContinuous03(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Actor secondRootActor = CreateRenderableActorSuccess(application, "aFile.jpg"); Stage::GetCurrent().Add(secondRootActor); @@ -2030,7 +2045,7 @@ int UtcDaliRenderTaskContinuous04(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Actor secondRootActor = CreateRenderableActorFailed(application, "aFile.jpg"); Stage::GetCurrent().Add(secondRootActor); @@ -2061,7 +2076,7 @@ int UtcDaliRenderTaskOnce01(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Actor secondRootActor = CreateRenderableActorSuccess(application, "aFile.jpg"); @@ -2099,7 +2114,7 @@ int UtcDaliRenderTaskOnce02(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Shader shader = CreateShader(); @@ -2147,7 +2162,7 @@ int UtcDaliRenderTaskOnce03(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Actor secondRootActor = CreateRenderableActorSuccess(application, "aFile.jpg"); Stage::GetCurrent().Add(secondRootActor); @@ -2192,7 +2207,7 @@ int UtcDaliRenderTaskOnce04(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Shader shader = CreateShader(); @@ -2244,7 +2259,7 @@ int UtcDaliRenderTaskOnceNoSync01(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Actor secondRootActor = CreateRenderableActorSuccess(application, "aFile.jpg"); Stage::GetCurrent().Add(secondRootActor); @@ -2274,7 +2289,7 @@ int UtcDaliRenderTaskOnceNoSync02(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Shader shader = CreateShader(); @@ -2318,7 +2333,7 @@ int UtcDaliRenderTaskOnceNoSync03(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Actor secondRootActor = CreateRenderableActorSuccess(application, "aFile.jpg"); Stage::GetCurrent().Add(secondRootActor); @@ -2355,7 +2370,7 @@ int UtcDaliRenderTaskOnceNoSync04(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Shader shader = CreateShader(); @@ -2410,7 +2425,7 @@ int UtcDaliRenderTaskOnceNoSync05(void) Actor rootActor = Actor::New(); Stage::GetCurrent().Add( rootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Actor secondRootActor = CreateRenderableActorFailed(application, "aFile.jpg"); Stage::GetCurrent().Add(secondRootActor); @@ -2450,7 +2465,7 @@ int UtcDaliRenderTaskOnceChain01(void) Actor defaultRootActor = Actor::New(); // Root for default RT Stage::GetCurrent().Add( defaultRootActor ); - CameraActor offscreenCameraActor = CameraActor::New(); + CameraActor offscreenCameraActor = CameraActor::New( Size( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT ) ); Stage::GetCurrent().Add( offscreenCameraActor ); Actor firstRootActor = CreateRenderableActorSuccess(application, "aFile.jpg"); Stage::GetCurrent().Add(firstRootActor); diff --git a/automated-tests/src/dali/utc-Dali-Scene.cpp b/automated-tests/src/dali/utc-Dali-Scene.cpp new file mode 100644 index 000000000..a8b706ecd --- /dev/null +++ b/automated-tests/src/dali/utc-Dali-Scene.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2016 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. + * + */ + +#include + +#include +#include +#include + +// Internal headers are allowed here + +int UtcDaliSceneAdd(void) +{ + TestApplication application; + tet_infoline("Testing Dali::Integration::Scene::Add"); + + Dali::Integration::Scene scene = application.GetScene(); + + Actor actor = Actor::New(); + DALI_TEST_CHECK( !actor.OnStage() ); + + scene.Add( actor ); + DALI_TEST_CHECK( actor.OnStage() ); + + END_TEST; +} + +int UtcDaliSceneRemove(void) +{ + TestApplication application; + tet_infoline("Testing Dali::Integration::Scene::Remove"); + + Dali::Integration::Scene scene = application.GetScene(); + + Actor actor = Actor::New(); + DALI_TEST_CHECK( !actor.OnStage() ); + + scene.Add( actor ); + DALI_TEST_CHECK( actor.OnStage() ); + + scene.Remove(actor); + DALI_TEST_CHECK( !actor.OnStage() ); + + END_TEST; +} + +int UtcDaliSceneGetSize(void) +{ + TestApplication application; + tet_infoline("Testing Dali::Integration::Scene::GetSize"); + + Dali::Integration::Scene scene = application.GetScene(); + Size size = scene.GetSize(); + DALI_TEST_EQUALS( TestApplication::DEFAULT_SURFACE_WIDTH, size.width, TEST_LOCATION ); + DALI_TEST_EQUALS( TestApplication::DEFAULT_SURFACE_HEIGHT, size.height, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliSceneGetDpi(void) +{ + TestApplication application; // Initializes core DPI to default values + + // Test that setting core DPI explicitly also sets up the scene's DPI. + Dali::Integration::Scene scene = application.GetScene(); + scene.SetDpi( Vector2(200.0f, 180.0f) ); + Vector2 dpi = scene.GetDpi(); + DALI_TEST_EQUALS( dpi.x, 200.0f, TEST_LOCATION ); + DALI_TEST_EQUALS( dpi.y, 180.0f, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliSceneGetRenderTaskList(void) +{ + TestApplication application; + tet_infoline("Testing Dali::Integration::Scene::GetRenderTaskList"); + + Dali::Integration::Scene scene = application.GetScene(); + + // Check we get a valid instance. + const RenderTaskList& tasks = scene.GetRenderTaskList(); + + // There should be 1 task by default. + DALI_TEST_EQUALS( tasks.GetTaskCount(), 1u, TEST_LOCATION ); + + // RenderTaskList has it's own UTC tests. + // But we can confirm that GetRenderTaskList in Stage retrieves the same RenderTaskList each time. + RenderTask newTask = scene.GetRenderTaskList().CreateTask(); + + DALI_TEST_EQUALS( scene.GetRenderTaskList().GetTask( 1 ), newTask, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliSceneGetRootLayer(void) +{ + TestApplication application; + tet_infoline("Testing Dali::Integration::Scene::GetRootLayer"); + + Dali::Integration::Scene scene = application.GetScene(); + Layer layer = scene.GetLayer( 0 ); + DALI_TEST_CHECK( layer ); + + // Check that GetRootLayer() correctly retreived layer 0. + DALI_TEST_CHECK( scene.GetRootLayer() == layer ); + + END_TEST; +} + +int UtcDaliSceneGetLayerCount(void) +{ + TestApplication application; + tet_infoline("Testing Dali::Integration::Scene::GetLayerCount"); + + Dali::Integration::Scene scene = application.GetScene(); + // Initially we have a default layer + DALI_TEST_EQUALS( scene.GetLayerCount(), 1u, TEST_LOCATION ); + + Layer layer = Layer::New(); + scene.Add( layer ); + + DALI_TEST_EQUALS( scene.GetLayerCount(), 2u, TEST_LOCATION ); + END_TEST; +} + +int UtcDaliSceneGetLayer(void) +{ + TestApplication application; + tet_infoline("Testing Dali::Integration::Scene::GetLayer"); + + Dali::Integration::Scene scene = application.GetScene(); + + Layer rootLayer = scene.GetLayer( 0 ); + DALI_TEST_CHECK( rootLayer ); + + Layer layer = Layer::New(); + scene.Add( layer ); + + Layer sameLayer = scene.GetLayer( 1 ); + DALI_TEST_CHECK( layer == sameLayer ); + + END_TEST; +} + diff --git a/automated-tests/src/dali/utc-Dali-Stage.cpp b/automated-tests/src/dali/utc-Dali-Stage.cpp index 954957f7a..a3fb8f2f0 100755 --- a/automated-tests/src/dali/utc-Dali-Stage.cpp +++ b/automated-tests/src/dali/utc-Dali-Stage.cpp @@ -591,7 +591,8 @@ int UtcDaliStageGetDpiP2(void) TestApplication application; // Initializes core DPI to default values // Test that setting core DPI explicitly also sets up the Stage's DPI. - application.GetCore().SetDpi( 200, 180 ); + Dali::Integration::Scene scene = application.GetScene(); + scene.SetDpi( Vector2(200.0f, 180.0f) ); Stage stage = Stage::GetCurrent(); Vector2 dpi = stage.GetDpi(); diff --git a/build/tizen/dali-core/Makefile.am b/build/tizen/dali-core/Makefile.am index c9f9f0731..9242d3b91 100644 --- a/build/tizen/dali-core/Makefile.am +++ b/build/tizen/dali-core/Makefile.am @@ -146,6 +146,7 @@ linker_test_SOURCES = linker-test.cpp \ ../../../automated-tests/src/dali/dali-test-suite-utils/test-application.cpp \ ../../../automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.cpp \ ../../../automated-tests/src/dali/dali-test-suite-utils/test-render-controller.cpp \ + ../../../automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp \ ../../../automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp \ ../../../automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.cpp \ ../../../automated-tests/src/dali/dali-test-suite-utils/test-gl-sync-abstraction.cpp \ diff --git a/dali/integration-api/CMakeLists.txt b/dali/integration-api/CMakeLists.txt index 76346b5d1..a856c3b6f 100644 --- a/dali/integration-api/CMakeLists.txt +++ b/dali/integration-api/CMakeLists.txt @@ -8,6 +8,7 @@ SET(SOURCES ${SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/input-options.cpp ${CMAKE_CURRENT_SOURCE_DIR}/lockless-buffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/render-task-list-integ.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/scene.cpp ${CMAKE_CURRENT_SOURCE_DIR}/events/event.cpp ${CMAKE_CURRENT_SOURCE_DIR}/events/gesture-event.cpp ${CMAKE_CURRENT_SOURCE_DIR}/events/hover-event-integ.cpp @@ -41,6 +42,7 @@ SET(INTEGRATION_API_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/platform-abstraction.h ${CMAKE_CURRENT_SOURCE_DIR}/lockless-buffer.h ${CMAKE_CURRENT_SOURCE_DIR}/render-task-list-integ.h + ${CMAKE_CURRENT_SOURCE_DIR}/scene.h ${CMAKE_CURRENT_SOURCE_DIR}/events/event.h ${CMAKE_CURRENT_SOURCE_DIR}/events/gesture-event.h diff --git a/dali/integration-api/core.cpp b/dali/integration-api/core.cpp index de8714f73..b14df7c2f 100644 --- a/dali/integration-api/core.cpp +++ b/dali/integration-api/core.cpp @@ -17,9 +17,12 @@ // CLASS HEADER #include +#include // INTERNAL INCLUDES #include +#include +#include #include #include #include @@ -60,6 +63,11 @@ Core::~Core() delete mImpl; } +void Core::Initialize() +{ + mImpl->Initialize(); +} + ContextNotifierInterface* Core::GetContextNotifier() { return mImpl->GetContextNotifier(); @@ -80,19 +88,9 @@ void Core::RecoverFromContextLoss() mImpl->RecoverFromContextLoss(); } -void Core::SurfaceResized(uint32_t width, uint32_t height) -{ - mImpl->SurfaceResized(width, height); -} - -void Core::SetTopMargin( uint32_t margin ) -{ - mImpl->SetTopMargin(margin); -} - -void Core::SetDpi( uint32_t dpiHorizontal, uint32_t dpiVertical) +void Core::SurfaceResized( Integration::RenderSurface* surface ) { - mImpl->SetDpi(dpiHorizontal, dpiVertical); + mImpl->SurfaceResized(surface); } void Core::SceneCreated() diff --git a/dali/integration-api/core.h b/dali/integration-api/core.h index f7e11b7a4..45d758245 100644 --- a/dali/integration-api/core.h +++ b/dali/integration-api/core.h @@ -30,6 +30,9 @@ namespace Dali { +class Layer; +class RenderTaskList; + namespace Internal { class Core; @@ -44,6 +47,7 @@ class GlSyncAbstraction; class PlatformAbstraction; class Processor; class RenderController; +class RenderSurface; struct Event; struct TouchData; @@ -247,6 +251,11 @@ public: */ ~Core(); + /** + * Initialize the core + */ + void Initialize(); + // GL Context Lifecycle /** @@ -286,31 +295,9 @@ public: * This should be done at least once i.e. after the first call to ContextCreated(). * The Core will use the surface size for camera calculations, and to set the GL viewport. * Multi-threading note: this method should be called from the main thread - * @param[in] width The new surface width. - * @param[in] height The new surface height. - */ - void SurfaceResized( uint32_t width, uint32_t height ); - - /** - * Notify the Core about the top margin size. - * Available stage size is reduced by this size. - * The stage is located below the size at the top of the display - * It is mainly useful for indicator in mobile device - * @param[in] margin margin size - */ - void SetTopMargin( uint32_t margin ); - - // Core setters - - /** - * Notify the Core about the display's DPI values. - * This should be done after the display is initialized and a Core instance is created. - * The Core will use the DPI values for font rendering. - * Multi-threading note: this method should be called from the main thread - * @param[in] dpiHorizontal Horizontal DPI value. - * @param[in] dpiVertical Vertical DPI value. + * @param[in] surface The resized surface */ - void SetDpi( uint32_t dpiHorizontal, uint32_t dpiVertical ); + void SurfaceResized( Integration::RenderSurface* surface ); // Core Lifecycle diff --git a/dali/integration-api/file.list b/dali/integration-api/file.list index e778e614e..db6517ce8 100644 --- a/dali/integration-api/file.list +++ b/dali/integration-api/file.list @@ -9,6 +9,7 @@ platform_abstraction_src_files = \ $(platform_abstraction_src_dir)/input-options.cpp \ $(platform_abstraction_src_dir)/lockless-buffer.cpp \ $(platform_abstraction_src_dir)/render-task-list-integ.cpp \ + $(platform_abstraction_src_dir)/scene.cpp \ $(platform_abstraction_src_dir)/events/event.cpp \ $(platform_abstraction_src_dir)/events/gesture-event.cpp \ $(platform_abstraction_src_dir)/events/hover-event-integ.cpp \ @@ -42,7 +43,9 @@ platform_abstraction_header_files = \ $(platform_abstraction_src_dir)/platform-abstraction.h \ $(platform_abstraction_src_dir)/processor-interface.h \ $(platform_abstraction_src_dir)/lockless-buffer.h \ - $(platform_abstraction_src_dir)/render-task-list-integ.h + $(platform_abstraction_src_dir)/render-task-list-integ.h \ + $(platform_abstraction_src_dir)/scene.h \ + $(platform_abstraction_src_dir)/render-surface.h platform_abstraction_events_header_files = \ $(platform_abstraction_src_dir)/events/event.h \ diff --git a/dali/integration-api/render-surface.h b/dali/integration-api/render-surface.h new file mode 100644 index 000000000..17f22e9d7 --- /dev/null +++ b/dali/integration-api/render-surface.h @@ -0,0 +1,215 @@ +#ifndef DALI_RENDER_SURFACE_H +#define DALI_RENDER_SURFACE_H + +/* + * Copyright (c) 2019 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 + +namespace Dali +{ + +class DisplayConnection; +class ThreadSynchronizationInterface; + +namespace Internal +{ + +namespace Adaptor +{ + +class GraphicsInterface; + +} // namespace Adaptor + +} // namespace Internal + +/** + * @brief The position and size of the render surface. + */ +typedef Dali::Rect PositionSize; + +namespace Integration +{ + +class GlAbstraction; + +/** + * @brief Interface for a render surface onto which Dali draws. + * + * Dali::Adaptor requires a render surface to draw on to. This is + * usually a window in the native windowing system, or some other + * mapped pixel buffer. + * + * Dali::Application will automatically create a render surface using a window. + * + * The implementation of the factory method below should choose an appropriate + * implementation of RenderSurface for the given platform + */ + +class DALI_CORE_API RenderSurface +{ +public: + + enum Type + { + WINDOW_RENDER_SURFACE, + PIXMAP_RENDER_SURFACE, + NATIVE_RENDER_SURFACE + }; + + /** + * @brief Constructor + * Inlined as this is a pure abstract interface + */ + RenderSurface() {} + + /** + * @brief Virtual Destructor. + * Inlined as this is a pure abstract interface + */ + virtual ~RenderSurface() {} + + /** + * @brief Return the size and position of the surface. + * @return The position and size + */ + virtual PositionSize GetPositionSize() const = 0; + + /** + * @brief Get DPI + * @param[out] dpiHorizontal set to the horizontal dpi + * @param[out] dpiVertical set to the vertical dpi + */ + virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) = 0; + + /** + * @brief InitializeGraphics the platform specific graphics surface interfaces + */ + virtual void InitializeGraphics() = 0; + + /** + * @brief Creates the Surface + */ + virtual void CreateSurface() = 0; + + /** + * @brief Destroys the Surface + */ + virtual void DestroySurface() = 0; + + /** + * @brief Replace the Surface + * @return true if context was lost + */ + virtual bool ReplaceGraphicsSurface() = 0; + + /** + * @brief Resizes the underlying surface. + * @param[in] The dimensions of the new position + */ + virtual void MoveResize( Dali::PositionSize positionSize ) = 0; + + /** + * @brief Called when Render thread has started + */ + virtual void StartRender() = 0; + + /** + * @brief Invoked by render thread before Core::Render + * 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 + * @return True if the operation is successful, False if the operation failed + */ + virtual bool PreRender( bool resizingSurface ) = 0; + + /** + * @brief Invoked by render thread after Core::Render + * @param[in] renderToFbo True if render to FBO. + * @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; + + /** + * @brief Invoked by render thread when the thread should be stop + */ + virtual void StopRender() = 0; + + /** + * @brief Invoked by Event Thread when the compositor lock should be released and rendering should resume. + */ + virtual void ReleaseLock() = 0; + + /** + * @brief Gets the surface type + */ + virtual RenderSurface::Type GetSurfaceType() = 0; + + /** + * @brief Makes the graphics context current + */ + virtual void MakeContextCurrent() = 0; + + /** + * @brief Gets whether the depth buffer is required + * @return TRUE if the depth buffer is required + */ + virtual Integration::DepthBufferAvailable GetDepthBufferRequired() = 0; + + /** + * @brief Gets whether the stencil buffer is required + * @return TRUE if the stencil buffer is required + */ + virtual Integration::StencilBufferAvailable GetStencilBufferRequired() = 0; + + /** + * @brief Sets the background color of the surface. + * @param[in] color The new background color + */ + virtual void SetBackgroundColor(Vector4 color) = 0; + + /** + * @brief Gets the background color of the surface. + * @return The background color + */ + virtual Vector4 GetBackgroundColor() = 0; + +private: + + /** + * @brief Undefined copy constructor. RenderSurface cannot be copied + */ + RenderSurface( const RenderSurface& rhs ) = delete; + + /** + * @brief Undefined assignment operator. RenderSurface cannot be copied + */ + RenderSurface& operator=( const RenderSurface& rhs ) = delete; +}; + +} // namespace Integration + +} // namespace Dali + +#endif // DALI_RENDER_SURFACE_H diff --git a/dali/integration-api/scene.cpp b/dali/integration-api/scene.cpp new file mode 100644 index 000000000..717132cb2 --- /dev/null +++ b/dali/integration-api/scene.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2019 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 +#include +#include + +namespace Dali +{ + +namespace Integration +{ + +Scene Scene::New( Size size ) +{ + Internal::ScenePtr internal = Internal::Scene::New( size ); + return Scene(internal.Get()); +} + +Scene Scene::DownCast( BaseHandle handle ) +{ + return Scene( dynamic_cast( handle.GetObjectPtr()) ); +} + +Scene::Scene() +{ +} + +Scene::~Scene() +{ +} + +Scene::Scene( const Scene& handle ) +:BaseHandle(handle) +{ +} + +Scene::Scene( Internal::Scene* internal ) +: BaseHandle(internal) +{ +} + +Scene& Scene::operator=( const Scene& rhs ) +{ + BaseHandle::operator=(rhs); + return *this; +} + +void Scene::Add( Actor& actor ) +{ + GetImplementation(*this).Add( GetImplementation(actor) ); +} + +void Scene::Remove( Actor& actor ) +{ + GetImplementation(*this).Remove( GetImplementation(actor) ); +} + +Size Scene::GetSize() const +{ + return GetImplementation(*this).GetSize(); +} + +void Scene::SetDpi( Vector2 dpi ) +{ + GetImplementation(*this).SetDpi( dpi ); +} + +Vector2 Scene::GetDpi() const +{ + return GetImplementation(*this).GetDpi(); +} + +RenderTaskList Scene::GetRenderTaskList() const +{ + return RenderTaskList( &GetImplementation(*this).GetRenderTaskList() ); +} + +Layer Scene::GetRootLayer() const +{ + return GetImplementation(*this).GetRootLayer(); +} + +uint32_t Scene::GetLayerCount() const +{ + return GetImplementation(*this).GetLayerCount(); +} + +Layer Scene::GetLayer( uint32_t depth ) const +{ + return GetImplementation(*this).GetLayer( depth ); +} + +void Scene::SetSurface( Integration::RenderSurface& surface ) +{ + GetImplementation(*this).SetSurface( surface ); +} + +} // Integration + +} // Dali diff --git a/dali/integration-api/scene.h b/dali/integration-api/scene.h new file mode 100644 index 000000000..83519b63c --- /dev/null +++ b/dali/integration-api/scene.h @@ -0,0 +1,195 @@ +#ifndef DALI_SCENE_H +#define DALI_SCENE_H + +/* + * Copyright (c) 2019 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 Actor; +class Layer; +class RenderTaskList; + +namespace Internal DALI_INTERNAL +{ + class Scene; +} + +namespace Integration +{ + +class RenderSurface; + +/** + * @brief + * + * Scene creates a "world" that can be bound to a surface for rendering. + * + */ +class DALI_CORE_API Scene : public BaseHandle +{ +public: + + /** + * @brief Create an initialized Scene handle. + * + * @param[in] size The size of the scene in pixels as a Vector + * + * @return a handle to a newly allocated Dali resource. + */ + static Scene New( Size size ); + + /** + * @brief Downcast an Object handle to Scene handle. + * + * If handle points to a Scene object the downcast produces + * valid handle. If not the returned handle is left uninitialized. + * @param[in] handle to An object + * @return handle to a Scene object or an uninitialized handle + */ + static Scene DownCast( BaseHandle handle ); + + /** + * @brief Create an uninitialized Scene handle. + * + * This can be initialized with Scene::New(). Calling member + * functions with an uninitialized Dali::Object is not allowed. + */ + Scene(); + + /** + * @brief Destructor + * + * This is non-virtual since derived Handle types must not contain data or virtual methods. + */ + ~Scene(); + + /** + * @brief This copy constructor is required for (smart) pointer semantics. + * + * @param [in] handle A reference to the copied handle + */ + Scene(const Scene& handle); + + /** + * @brief This assignment operator is required for (smart) pointer semantics. + * + * @param [in] rhs A reference to the copied handle + * @return A reference to this + */ + Scene& operator=(const Scene& rhs); + + /** + * @brief Adds a child Actor to the Scene. + * + * The child will be referenced. + * @param[in] actor The child + * @pre The actor has been initialized. + * @pre The actor does not have a parent. + */ + void Add(Actor& actor); + + /** + * @brief Removes a child Actor from the Scene. + * + * The child will be unreferenced. + * @param[in] actor The child + * @pre The actor has been added to the stage. + */ + void Remove(Actor& actor); + + /** + * @brief Returns the size of the Scene in pixels as a Vector. + * + * The x component will be the width of the Scene in pixels. + * The y component will be the height of the Scene in pixels. + * + * @return The size of the Scene as a Vector + */ + Size GetSize() const; + + /** + * Sets horizontal and vertical pixels per inch value that is used by the display + * @param[in] dpi Horizontal and vertical dpi value + */ + void SetDpi( Vector2 dpi ); + + /** + * @brief Retrieves the DPI of the display device to which the scene is connected. + * + * @return The horizontal and vertical DPI + */ + Vector2 GetDpi() const; + + /** + * @brief Retrieves the list of render-tasks. + * + * @return A valid handle to a RenderTaskList + */ + Dali::RenderTaskList GetRenderTaskList() const; + + /** + * @brief Returns the Scene's Root Layer. + * + * @return The root layer + */ + Layer GetRootLayer() const; + + /** + * @brief Queries the number of on-stage layers. + * + * Note that a default layer is always provided (count >= 1). + * @return The number of layers + */ + uint32_t GetLayerCount() const; + + /** + * @brief Retrieves the layer at a specified depth. + * + * @param[in] depth The depth + * @return The layer found at the given depth + * @pre Depth is less than layer count; see GetLayerCount(). + */ + Layer GetLayer( uint32_t depth ) const; + + /** + * @brief Binds the rendering surface to the scene + * + * @return The root layer + */ + void SetSurface( Integration::RenderSurface& surface ); + +public: // Not intended for application developers + + /** + * @brief This constructor is used by Dali::New() methods. + * + * @param[in] scene A pointer to an internal Scene resource + */ + explicit DALI_INTERNAL Scene(Internal::Scene* scene); +}; + +} // namespace Integration + +} // namespace Dali + +#endif // DALI_SCENE_H diff --git a/dali/internal/CMakeLists.txt b/dali/internal/CMakeLists.txt index 38cfe0603..47d172254 100644 --- a/dali/internal/CMakeLists.txt +++ b/dali/internal/CMakeLists.txt @@ -36,6 +36,7 @@ SET(SOURCES ${SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/event/common/property-notification-impl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/event/common/property-notification-manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/event/common/property-helper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/event/common/scene-impl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/event/common/stage-impl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/event/common/thread-local-storage.cpp ${CMAKE_CURRENT_SOURCE_DIR}/event/common/type-info-impl.cpp @@ -98,7 +99,8 @@ SET(SOURCES ${SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/render/gl-resources/gl-call-debug.cpp ${CMAKE_CURRENT_SOURCE_DIR}/render/gl-resources/gpu-buffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/render/queue/render-queue.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/render/renderers/render-frame-buffer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/renderers/render-texture-frame-buffer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/render/renderers/render-surface-frame-buffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/render/renderers/render-geometry.cpp ${CMAKE_CURRENT_SOURCE_DIR}/render/renderers/render-property-buffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/render/renderers/render-renderer.cpp diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index 7d6f52315..4ddbc042c 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -89,7 +91,8 @@ Core::Core( RenderController& renderController, Integration::StencilBufferAvailable stencilBufferAvailable ) : mRenderController( renderController ), mPlatform(platform), - mProcessingEvent(false) + mProcessingEvent(false), + mForceNextUpdate( false ) { // Create the thread local storage CreateThreadLocalStorage(); @@ -122,13 +125,13 @@ Core::Core( RenderController& renderController, mRenderManager->SetShaderSaver( *mUpdateManager ); - mStage = IntrusivePtr( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager, mRenderController ) ); + mObjectRegistry = ObjectRegistry::New(); + + mStage = IntrusivePtr( Stage::New( *mUpdateManager ) ); // This must be called after stage is created but before stage initialization mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) ); - mStage->Initialize( renderToFboEnabled == Integration::RenderToFrameBuffer::TRUE ); - mGestureEventProcessor = new GestureEventProcessor( *mStage, *mUpdateManager, gestureManager, mRenderController ); mEventProcessor = new EventProcessor( *mStage, *mNotificationManager, *mGestureEventProcessor ); @@ -154,17 +157,21 @@ Core::~Core() delete tls; } + mObjectRegistry.Reset(); + // Stop relayout requests being raised on stage destruction mRelayoutController.Reset(); - // Clean-up stage - remove default camera and root layer - mStage->Uninitialize(); - // remove (last?) reference to stage mStage.Reset(); } +void Core::Initialize() +{ + mStage->Initialize( *mScenes[0] ); +} + Integration::ContextNotifierInterface* Core::GetContextNotifier() { return mStage.Get(); @@ -187,27 +194,15 @@ void Core::ContextDestroyed() mRenderManager->ContextDestroyed(); } -void Core::SurfaceResized( uint32_t width, uint32_t height ) +void Core::SurfaceResized( Integration::RenderSurface* surface ) { - mStage->SurfaceResized( static_cast( width ), static_cast( height ) ); - - // The stage-size may be less than surface-size (reduced by top-margin) - Vector2 size = mStage->GetSize(); - mRelayoutController->SetStageSize( static_cast( size.width ), static_cast( size.height ) ); // values get truncated -} - -void Core::SetTopMargin( uint32_t margin ) -{ - mStage->SetTopMargin( margin ); - - // The stage-size may be less than surface-size (reduced by top-margin) - Vector2 size = mStage->GetSize(); - mRelayoutController->SetStageSize( static_cast( size.width ), static_cast( size.height ) ); // values get truncated -} - -void Core::SetDpi( uint32_t dpiHorizontal, uint32_t dpiVertical ) -{ - mStage->SetDpi( Vector2( static_cast( dpiHorizontal ), static_cast( dpiVertical ) ) ); + for( auto iter = mScenes.begin(); iter != mScenes.end(); ++iter ) + { + if( (*iter)->GetSurface() == surface ) + { + (*iter)->SetSurface( *surface ); + } + } } void Core::Update( float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds, Integration::UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo ) @@ -244,6 +239,12 @@ void Core::SceneCreated() mStage->EmitSceneCreatedSignal(); mRelayoutController->OnApplicationSceneCreated(); + + for( auto iter = mScenes.begin(); iter != mScenes.end(); ++iter ) + { + Dali::Actor sceneRootLayer = (*iter)->GetRootLayer(); + mRelayoutController->RequestRelayoutTree( sceneRootLayer ); + } } void Core::QueueEvent( const Integration::Event& event ) @@ -282,7 +283,10 @@ void Core::ProcessEvents() // Rebuild depth tree after event processing has finished - mStage->RebuildDepthTree(); + for( auto iter = mScenes.begin(); iter != mScenes.end(); ++iter ) + { + (*iter)->RebuildDepthTree(); + } // Flush any queued messages for the update-thread const bool messagesToProcess = mUpdateManager->FlushQueue(); @@ -290,7 +294,7 @@ void Core::ProcessEvents() // Check if the touch or gestures require updates. const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate(); // Check if the next update is forced. - const bool forceUpdate = mStage->IsNextUpdateForced(); + const bool forceUpdate = IsNextUpdateForced(); if( messagesToProcess || gestureNeedsUpdate || forceUpdate ) { @@ -377,6 +381,40 @@ RelayoutController& Core::GetRelayoutController() return *(mRelayoutController.Get()); } +ObjectRegistry& Core::GetObjectRegistry() const +{ + return *(mObjectRegistry.Get()); +} + +EventThreadServices& Core::GetEventThreadServices() +{ + return *this; +} + +PropertyNotificationManager& Core::GetPropertyNotificationManager() const +{ + return *(mPropertyNotificationManager); +} + +AnimationPlaylist& Core::GetAnimationPlaylist() const +{ + return *(mAnimationPlaylist); +} + +void Core::AddScene( Scene* scene ) +{ + mScenes.push_back( scene ); +} + +void Core::RemoveScene( Scene* scene ) +{ + auto iter = std::find( mScenes.begin(), mScenes.end(), scene ); + if( iter != mScenes.end() ) + { + mScenes.erase( iter ); + } +} + void Core::CreateThreadLocalStorage() { // a pointer to the ThreadLocalStorage object will be stored in TLS @@ -384,6 +422,45 @@ void Core::CreateThreadLocalStorage() new ThreadLocalStorage(this); } +void Core::RegisterObject( Dali::BaseObject* object ) +{ + mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry(); + mObjectRegistry->RegisterObject( object ); +} + +void Core::UnregisterObject( Dali::BaseObject* object ) +{ + mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry(); + mObjectRegistry->UnregisterObject( object ); +} + +Integration::RenderController& Core::GetRenderController() +{ + return mRenderController; +} + +uint32_t* Core::ReserveMessageSlot( uint32_t size, bool updateScene ) +{ + return mUpdateManager->ReserveMessageSlot( size, updateScene ); +} + +BufferIndex Core::GetEventBufferIndex() const +{ + return mUpdateManager->GetEventBufferIndex(); +} + +void Core::ForceNextUpdate() +{ + mForceNextUpdate = true; +} + +bool Core::IsNextUpdateForced() +{ + bool nextUpdateForced = mForceNextUpdate; + mForceNextUpdate = false; + return nextUpdateForced; +} + } // namespace Internal } // namespace Dali diff --git a/dali/internal/common/core-impl.h b/dali/internal/common/core-impl.h index d4aa55fe7..bd94c435a 100644 --- a/dali/internal/common/core-impl.h +++ b/dali/internal/common/core-impl.h @@ -24,9 +24,12 @@ #include #include #include +#include #include #include #include +#include +#include namespace Dali { @@ -41,6 +44,7 @@ class GlAbstraction; class GlSyncAbstraction; class UpdateStatus; class RenderStatus; +class RenderSurface; struct Event; struct TouchData; } @@ -56,6 +60,7 @@ class GestureEventProcessor; class ShaderFactory; class TouchResampler; class RelayoutController; +class EventThreadServices; namespace SceneGraph { @@ -68,7 +73,7 @@ class RenderTaskProcessor; /** * Internal class for Dali::Integration::Core */ -class Core +class Core : public EventThreadServices { public: @@ -90,6 +95,11 @@ public: */ ~Core(); + /** + * @copydoc Dali::Integration::Core::Initialize() + */ + void Initialize(); + /** * @copydoc Dali::Integration::Core::GetContextNotifier() */ @@ -111,19 +121,9 @@ public: void RecoverFromContextLoss(); /** - * @copydoc Dali::Integration::Core::SurfaceResized(uint32_t, uint32_t) - */ - void SurfaceResized(uint32_t width, uint32_t height); - - /** - * @copydoc Dali::Integration::Core::SetTopMargin( uint32_t margin ) + * @copydoc Dali::Integration::Core::SurfaceResized(Integration::RenderSurface*) */ - void SetTopMargin( uint32_t margin ); - - /** - * @copydoc Dali::Integration::Core::SetDpi(uint32_t, uint32_t) - */ - void SetDpi(uint32_t dpiHorizontal, uint32_t dpiVertical); + void SurfaceResized( Integration::RenderSurface* surface ); /** * @copydoc Dali::Integration::Core::SetMinimumFrameTimeInterval(uint32_t) @@ -170,6 +170,58 @@ public: */ void UnregisterProcessor( Dali::Integration::Processor& processor ); + /** + * @copydoc Dali::Internal::ThreadLocalStorage::AddScene() + */ + void AddScene( Scene* scene ); + + /** + * @copydoc Dali::Internal::ThreadLocalStorage::RemoveScene() + */ + void RemoveScene( Scene* scene ); + +public: // Implementation of EventThreadServices + + /** + * @copydoc EventThreadServices::RegisterObject + */ + void RegisterObject( BaseObject* object) override; + + /** + * @copydoc EventThreadServices::UnregisterObject + */ + void UnregisterObject( BaseObject* object) override; + + /** + * @copydoc EventThreadServices::GetUpdateManager + */ + SceneGraph::UpdateManager& GetUpdateManager() override; + + /** + * @copydoc EventThreadServices::GetRenderController + */ + Integration::RenderController& GetRenderController() override; + + /** + * @copydoc EventThreadServices::ReserveMessageSlot + */ + uint32_t* ReserveMessageSlot( uint32_t size, bool updateScene ) override; + + /** + * @copydoc EventThreadServices::GetEventBufferIndex + */ + BufferIndex GetEventBufferIndex() const override; + + /** + * @copydoc EventThreadServices::ForceNextUpdate + */ + void ForceNextUpdate() override; + + /** + * @copydoc EventThreadServices::IsNextUpdateForced + */ + bool IsNextUpdateForced() override; + private: /** * Run each registered processor @@ -190,12 +242,6 @@ private: */ Integration::PlatformAbstraction& GetPlatform(); - /** - * Returns the update manager. - * @return A reference to the update manager. - */ - SceneGraph::UpdateManager& GetUpdateManager(); - /** * Returns the render manager. * @return A reference to the render manager. @@ -226,13 +272,37 @@ private: */ RelayoutController& GetRelayoutController(); + /** + * @brief Gets the Object registry. + * @return A reference to the object registry + */ + ObjectRegistry& GetObjectRegistry() const; + + /** + * @brief Gets the event thread services. + * @return A reference to the event thread services + */ + EventThreadServices& GetEventThreadServices(); + + /** + * @brief Gets the property notification manager. + * @return A reference to the property notification manager + */ + PropertyNotificationManager& GetPropertyNotificationManager() const; + + /** + * @brief Gets the animation play list. + * @return A reference to the animation play list + */ + AnimationPlaylist& GetAnimationPlaylist() const; + private: /** * Undefined copy and assignment operators */ - Core(const Core& core); // No definition - Core& operator=(const Core& core); // No definition + Core(const Core& core) = delete; // No definition + Core& operator=(const Core& core) = delete; // No definition /** * Create Thread local storage @@ -248,7 +318,6 @@ private: AnimationPlaylistOwner mAnimationPlaylist; ///< For 'Fire and forget' animation support OwnerPointer mPropertyNotificationManager; ///< For safe signal emmision of property changed notifications IntrusivePtr< RelayoutController > mRelayoutController; ///< Size negotiation relayout controller - bool mProcessingEvent : 1; ///< True during ProcessEvents() OwnerPointer mRenderTaskProcessor; ///< Handles the processing of render tasks OwnerPointer mRenderManager; ///< Render manager @@ -260,6 +329,14 @@ private: OwnerPointer mEventProcessor; ///< The event processor Dali::Vector mProcessors; ///< Registered processors (not owned) + std::vector mScenes; ///< A container of scenes that bound to a surface for rendering, owned by Core + + // The object registry + ObjectRegistryPtr mObjectRegistry; + + bool mProcessingEvent : 1; ///< True during ProcessEvents() + bool mForceNextUpdate:1; ///< True if the next rendering is really required. + friend class ThreadLocalStorage; }; diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index d2b33c9fa..a3504e539 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include #include @@ -412,7 +414,8 @@ const SceneGraph::Node* Actor::CreateNode() // create node. Nodes are owned by the update manager SceneGraph::Node* node = SceneGraph::Node::New(); OwnerPointer< SceneGraph::Node > transferOwnership( node ); - AddNodeMessage( Stage::GetCurrent()->GetUpdateManager(), transferOwnership ); + Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal(); + AddNodeMessage( tls->GetUpdateManager(), transferOwnership ); return node; } @@ -792,20 +795,19 @@ const Vector3& Actor::GetCurrentWorldPosition() const const Vector2 Actor::GetCurrentScreenPosition() const { - StagePtr stage = Stage::GetCurrent(); - if( stage && OnStage() ) + if( mScene && OnStage() ) { Vector3 worldPosition = GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() ); - Vector3 cameraPosition = stage->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() ); + Vector3 cameraPosition = mScene->GetDefaultCameraActor().GetNode().GetWorldPosition( GetEventThreadServices().GetEventBufferIndex() ); worldPosition -= cameraPosition; Vector3 actorSize = GetCurrentSize() * GetCurrentWorldScale(); - Vector2 halfStageSize( stage->GetSize() * 0.5f ); // World position origin is center of stage + Vector2 halfSceneSize( mScene->GetSize() * 0.5f ); // World position origin is center of scene Vector3 halfActorSize( actorSize * 0.5f ); Vector3 anchorPointOffSet = halfActorSize - actorSize * ( mPositionUsesAnchorPoint ? GetCurrentAnchorPoint() : AnchorPoint::TOP_LEFT ); - return Vector2( halfStageSize.width + worldPosition.x - anchorPointOffSet.x, - halfStageSize.height + worldPosition.y - anchorPointOffSet.y ); + return Vector2( halfSceneSize.width + worldPosition.x - anchorPointOffSet.x, + halfSceneSize.height + worldPosition.y - anchorPointOffSet.y ); } return Vector2::ZERO; @@ -1499,10 +1501,9 @@ DrawMode::Type Actor::GetDrawMode() const bool Actor::ScreenToLocal( float& localX, float& localY, float screenX, float screenY ) const { // only valid when on-stage - StagePtr stage = Stage::GetCurrent(); - if( stage && OnStage() ) + if( mScene && OnStage() ) { - const RenderTaskList& taskList = stage->GetRenderTaskList(); + const RenderTaskList& taskList = mScene->GetRenderTaskList(); Vector2 converted( screenX, screenY ); @@ -2002,6 +2003,7 @@ bool Actor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra Actor::Actor( DerivedType derivedType, const SceneGraph::Node& node ) : Object( &node ), + mScene( nullptr ), mParent( NULL ), mChildren( NULL ), mRenderers( NULL ), @@ -2100,10 +2102,9 @@ void Actor::ConnectToStage( uint32_t parentDepth ) // It protects us when the Actor hierarchy is modified during OnStageConnectionExternal callbacks. ActorContainer connectionList; - StagePtr stage = Stage::GetCurrent(); - if( stage ) + if( mScene ) { - stage->RequestRebuildDepthTree(); + mScene->RequestRebuildDepthTree(); } // This stage is atomic i.e. not interrupted by user callbacks. @@ -2140,6 +2141,7 @@ void Actor::RecursiveConnectToStage( ActorContainer& connectionList, uint32_t de ActorConstIter endIter = mChildren->end(); for( ActorIter iter = mChildren->begin(); iter != endIter; ++iter ) { + (*iter)->SetScene( *mScene ); (*iter)->RecursiveConnectToStage( connectionList, depth + 1 ); } } @@ -2194,10 +2196,9 @@ void Actor::DisconnectFromStage() // It protects us when the Actor hierachy is modified during OnStageDisconnectionExternal callbacks. ActorContainer disconnectionList; - StagePtr stage = Stage::GetCurrent(); - if( stage ) + if( mScene ) { - stage->RequestRebuildDepthTree(); + mScene->RequestRebuildDepthTree(); } // This stage is atomic i.e. not interrupted by user callbacks @@ -3410,6 +3411,8 @@ void Actor::SetParent( Actor* parent ) mParent = parent; + mScene = parent->mScene; + if ( EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction parent->OnStage() ) { @@ -3435,6 +3438,8 @@ void Actor::SetParent( Actor* parent ) // Instruct each actor to discard pointers to the scene-graph DisconnectFromStage(); } + + mScene = nullptr; } } @@ -4782,10 +4787,9 @@ void Actor::RequestRebuildDepthTree() { if( mIsOnStage ) { - StagePtr stage = Stage::GetCurrent(); - if( stage ) + if( mScene ) { - stage->RequestRebuildDepthTree(); + mScene->RequestRebuildDepthTree(); } } } @@ -4969,6 +4973,16 @@ void Actor::LowerBelow( Internal::Actor& target ) } } +void Actor::SetScene( Scene& scene ) +{ + mScene = &scene; +} + +Scene& Actor::GetScene() const +{ + return *mScene; +} + void Actor::SetInheritLayoutDirection( bool inherit ) { if( mInheritLayoutDirection != inherit ) diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index c98701adf..9a27d8129 100755 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -54,6 +54,7 @@ class ActorGestureData; class Animation; class RenderTask; class Renderer; +class Scene; typedef std::vector< ActorPtr > ActorContainer; typedef ActorContainer::iterator ActorIter; @@ -1705,6 +1706,20 @@ public: */ void LowerBelow( Internal::Actor& target ); +public: + + /** + * Sets the scene which this actor is added to. + * @param[in] scene The scene + */ + void SetScene( Scene& scene ); + + /** + * Gets the scene which this actor is added to. + * @return The scene + */ + Scene& GetScene() const; + private: struct SendMessage @@ -1913,6 +1928,8 @@ private: protected: + Scene* mScene; ///< The scene the actor is added to + Actor* mParent; ///< Each actor (except the root) can have one parent ActorContainer* mChildren; ///< Container of referenced actors, lazily initialized RendererContainer* mRenderers; ///< Renderer container diff --git a/dali/internal/event/actors/camera-actor-impl.cpp b/dali/internal/event/actors/camera-actor-impl.cpp index 3d2138389..ae63c9f7e 100644 --- a/dali/internal/event/actors/camera-actor-impl.cpp +++ b/dali/internal/event/actors/camera-actor-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -28,9 +28,11 @@ #include #include #include +#include #include #include #include +#include #include namespace Dali @@ -368,30 +370,18 @@ bool CameraActor::GetInvertYAxis() const return mInvertYAxis; } -void CameraActor::SetPerspectiveProjection( const Size& size, const Vector2& stereoBias /* = Vector2::ZERO */ ) +void CameraActor::SetPerspectiveProjection( const Size& size ) { - float width = size.width; - float height = size.height; - - if( Size::ZERO == size ) - { - StagePtr stage = Stage::GetCurrent(); - if( stage ) - { - const Size& stageSize = stage->GetSize(); - - width = stageSize.width; - height = stageSize.height; - } - } - - if( ( width < Math::MACHINE_EPSILON_1000 ) || ( height < Math::MACHINE_EPSILON_1000 ) ) + if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) ) { - // On the stage initialization this method is called but the size has not been set. - // There is no point to set any value if width or height is zero. + // Not allowed to set the canvas size to be 0. + DALI_LOG_ERROR( "Canvas size can not be 0\n" ); return; } + float width = size.width; + float height = size.height; + float nearClippingPlane; float farClippingPlane; float cameraZ; diff --git a/dali/internal/event/actors/camera-actor-impl.h b/dali/internal/event/actors/camera-actor-impl.h index dc017f80a..1694ba306 100644 --- a/dali/internal/event/actors/camera-actor-impl.h +++ b/dali/internal/event/actors/camera-actor-impl.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_CAMERA_ACTOR_H /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -154,9 +154,8 @@ public: /** * @copydoc Dali::CameraActor::SetPerspectiveProjection() - * @param[in] stereoBias The frustum horizontal and vertical offset for stereoscopic cameras */ - void SetPerspectiveProjection( const Size& size, const Vector2& stereoBias = Vector2::ZERO ); + void SetPerspectiveProjection( const Size& size ); /** * @copydoc Dali::CameraActor::SetOrthographicProjection(const Vector2& size); diff --git a/dali/internal/event/actors/layer-impl.cpp b/dali/internal/event/actors/layer-impl.cpp index 033ee7b21..8040640b4 100644 --- a/dali/internal/event/actors/layer-impl.cpp +++ b/dali/internal/event/actors/layer-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -26,7 +26,8 @@ #include #include #include -#include +#include +#include using Dali::Internal::SceneGraph::UpdateManager; @@ -87,7 +88,7 @@ LayerPtr Layer::New() // create node, nodes are owned by UpdateManager SceneGraph::Layer* layerNode = SceneGraph::Layer::New(); OwnerPointer< SceneGraph::Node > transferOwnership( layerNode ); - AddNodeMessage( Stage::GetCurrent()->GetUpdateManager(), transferOwnership ); + AddNodeMessage( EventThreadServices::Get().GetUpdateManager(), transferOwnership ); LayerPtr layer( new Layer( Actor::LAYER, *layerNode ) ); // Second-phase construction @@ -257,10 +258,9 @@ void Layer::SetClippingBox(int x, int y, int width, int height) // Convert mClippingBox to GL based coordinates (from bottom-left) ClippingBox clippingBox( mClippingBox ); - StagePtr stage = Stage::GetCurrent(); - if( stage ) + if( mScene ) { - clippingBox.y = static_cast( stage->GetSize().height ) - clippingBox.y - clippingBox.height; + clippingBox.y = static_cast( mScene->GetSize().height ) - clippingBox.y - clippingBox.height; // layerNode is being used in a separate thread; queue a message to set the value SetClippingBoxMessage( GetEventThreadServices(), GetSceneLayerOnStage(), clippingBox ); diff --git a/dali/internal/event/animation/animation-impl.cpp b/dali/internal/event/animation/animation-impl.cpp index 587a96abd..876ec296d 100644 --- a/dali/internal/event/animation/animation-impl.cpp +++ b/dali/internal/event/animation/animation-impl.cpp @@ -140,29 +140,19 @@ void ValidateParameters( Property::Type propertyType, Property::Type destination AnimationPtr Animation::New(float durationSeconds) { - Stage* stage = Stage::GetCurrent(); - - if( stage ) + if( durationSeconds < 0.0f ) { - AnimationPlaylist& playlist = stage->GetAnimationPlaylist(); - - if( durationSeconds < 0.0f ) - { - DALI_LOG_WARNING("duration should be greater than 0.0f.\n"); - durationSeconds = 0.0f; - } + DALI_LOG_WARNING("duration should be greater than 0.0f.\n"); + durationSeconds = 0.0f; + } - AnimationPtr animation = new Animation( *stage, playlist, durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, DEFAULT_ALPHA_FUNCTION ); + ThreadLocalStorage& tls = ThreadLocalStorage::Get(); + AnimationPtr animation = new Animation( tls.GetEventThreadServices(), tls.GetAnimationPlaylist(), durationSeconds, DEFAULT_END_ACTION, DEFAULT_DISCONNECT_ACTION, DEFAULT_ALPHA_FUNCTION ); - // Second-phase construction - animation->Initialize(); + // Second-phase construction + animation->Initialize(); - return animation; - } - else - { - return NULL; - } + return animation; } Animation::Animation( EventThreadServices& eventThreadServices, AnimationPlaylist& playlist, float durationSeconds, EndAction endAction, EndAction disconnectAction, AlphaFunction defaultAlpha ) diff --git a/dali/internal/event/animation/constraint-base.cpp b/dali/internal/event/animation/constraint-base.cpp index 8ebbd6e09..c70b2516d 100644 --- a/dali/internal/event/animation/constraint-base.cpp +++ b/dali/internal/event/animation/constraint-base.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -54,7 +55,7 @@ inline void AddUnique( SceneGraph::PropertyOwnerContainer& propertyOwners, Scene } // unnamed namespace ConstraintBase::ConstraintBase( Object& object, Property::Index targetPropertyIndex, SourceContainer& sources ) -: mEventThreadServices( *Stage::GetCurrent() ), +: mEventThreadServices( EventThreadServices::Get() ), mTargetObject( &object ), mSceneGraphConstraint( NULL ), mSources( sources ), diff --git a/dali/internal/event/common/event-thread-services.cpp b/dali/internal/event/common/event-thread-services.cpp index 66e87e915..aa9e3346b 100644 --- a/dali/internal/event/common/event-thread-services.cpp +++ b/dali/internal/event/common/event-thread-services.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -25,6 +25,11 @@ namespace Dali namespace Internal { +EventThreadServices& EventThreadServices::Get() +{ + return ThreadLocalStorage::Get().GetEventThreadServices(); +} + bool EventThreadServices::IsCoreRunning() { return ThreadLocalStorage::Created(); diff --git a/dali/internal/event/common/event-thread-services.h b/dali/internal/event/common/event-thread-services.h index 80899507d..b6db04745 100644 --- a/dali/internal/event/common/event-thread-services.h +++ b/dali/internal/event/common/event-thread-services.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_EVENT_THREAD_SERVICES_H__ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -57,6 +57,12 @@ public: virtual ~EventThreadServices() { } + /** + * Get the EventThreadServices + * @return reference to the EventThreadServices + */ + static EventThreadServices& Get(); + /** * @brief Registers the object as created with the Object registry. * diff --git a/dali/internal/event/common/object-impl.cpp b/dali/internal/event/common/object-impl.cpp index 09e48c0b3..d6c5cea8d 100644 --- a/dali/internal/event/common/object-impl.cpp +++ b/dali/internal/event/common/object-impl.cpp @@ -948,7 +948,7 @@ DevelHandle::PropertySetSignalType& Object::PropertySetSignal() } Object::Object( const SceneGraph::PropertyOwner* sceneObject ) -: mEventThreadServices( *Stage::GetCurrent() ), +: mEventThreadServices( EventThreadServices::Get() ), mUpdateObject( sceneObject ), mTypeInfo( nullptr ), mConstraints( nullptr ), diff --git a/dali/internal/event/common/property-buffer-impl.cpp b/dali/internal/event/common/property-buffer-impl.cpp index ecd9a6972..c44df2ce8 100644 --- a/dali/internal/event/common/property-buffer-impl.cpp +++ b/dali/internal/event/common/property-buffer-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -20,7 +20,6 @@ // INTERNAL INCLUDES #include -#include #include namespace Dali @@ -170,7 +169,7 @@ PropertyBuffer::~PropertyBuffer() } PropertyBuffer::PropertyBuffer() -: mEventThreadServices( *Stage::GetCurrent() ), +: mEventThreadServices( EventThreadServices::Get() ), mRenderObject( NULL ), mBufferFormatSize( 0 ), mSize( 0 ) diff --git a/dali/internal/event/common/property-notification-impl.cpp b/dali/internal/event/common/property-notification-impl.cpp index a261fa29e..7e407cabb 100644 --- a/dali/internal/event/common/property-notification-impl.cpp +++ b/dali/internal/event/common/property-notification-impl.cpp @@ -46,21 +46,13 @@ PropertyNotificationPtr PropertyNotification::New(Property& target, UpdateManager& updateManager = tls.GetUpdateManager(); - StagePtr stage = Stage::GetCurrent(); - if( stage ) - { - PropertyNotificationManager& propertyNotificationManager = stage->GetPropertyNotificationManager(); - PropertyNotificationPtr propertyNotification = new PropertyNotification(updateManager, - propertyNotificationManager, - target, - componentIndex, - condition); - return propertyNotification; - } - else - { - return NULL; - } + PropertyNotificationManager& propertyNotificationManager = tls.GetPropertyNotificationManager(); + PropertyNotificationPtr propertyNotification = new PropertyNotification(updateManager, + propertyNotificationManager, + target, + componentIndex, + condition); + return propertyNotification; } PropertyNotification::PropertyNotification( UpdateManager& updateManager, diff --git a/dali/internal/event/common/scene-impl.cpp b/dali/internal/event/common/scene-impl.cpp new file mode 100644 index 000000000..f68060ea5 --- /dev/null +++ b/dali/internal/event/common/scene-impl.cpp @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2019 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using Dali::Internal::SceneGraph::Node; + +namespace Dali +{ + +namespace Internal +{ + +namespace +{ + +const Vector4 DEFAULT_BACKGROUND_COLOR(0.0f, 0.0f, 0.0f, 1.0f); // Default background color + +} //Unnamed namespace + +ScenePtr Scene::New( Size size ) +{ + ScenePtr scene = new Scene( size ); + + // Second-phase construction + scene->Initialize(); + + return scene; +} + +Scene::Scene( Size size ) +: mSurface( nullptr ), + mSize( size ), + mSurfaceSize( Vector2::ZERO ), + mDpi( Vector2::ZERO ), + mDepthTreeDirty( false ) +{ +} + +Scene::~Scene() +{ + if( mDefaultCamera ) + { + // its enough to release the handle so the object is released + // don't need to remove it from root actor as root actor will delete the object + mDefaultCamera.Reset(); + } + + if( mRootLayer ) + { + // we are closing down so just delete the root, no point emit disconnect + // signals or send messages to update + mRootLayer.Reset(); + } + + if( mRenderTaskList ) + { + mRenderTaskList.Reset(); + } + + if( ThreadLocalStorage::Created() ) + { + ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal(); + tls->RemoveScene( this ); + } +} + +void Scene::Initialize() +{ + ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal(); + + DALI_ASSERT_ALWAYS( tls && "Attempt to create scene before core exists!" ); + + tls->AddScene( this ); + + SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager(); + + // Create the ordered list of layers + mLayerList = LayerList::New( updateManager ); + + // The stage owns the default layer + mRootLayer = Layer::NewRoot( *mLayerList, updateManager ); + mRootLayer->SetName("RootLayer"); + mRootLayer->SetScene( *this ); + + // The root layer needs to have a fixed resize policy (as opposed to the default USE_NATURAL_SIZE). + // This stops actors parented to the stage having their relayout requests propagating + // up to the root layer, and down through other children unnecessarily. + mRootLayer->SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS ); + + // Create the default camera actor first; this is needed by the RenderTaskList + // The default camera attributes and position is such that children of the default layer, + // can be positioned at (0,0) and be at the top-left of the viewport. + mDefaultCamera = CameraActor::New( mSize ); + mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER); + Add(*(mDefaultCamera.Get())); + + // Create the list of render-tasks + mRenderTaskList = RenderTaskList::New(); + + // Create the default render-task + mRenderTaskList->CreateTask( mRootLayer.Get(), mDefaultCamera.Get() ); +} + +void Scene::Add(Actor& actor) +{ + mRootLayer->Add( actor ); +} + +void Scene::Remove(Actor& actor) +{ + mRootLayer->Remove( actor ); +} + +Size Scene::GetSize() const +{ + return mSize; +} + +void Scene::SetDpi(Vector2 dpi) +{ + mDpi = dpi; +} + +Vector2 Scene::GetDpi() const +{ + return mDpi; +} + +RenderTaskList& Scene::GetRenderTaskList() const +{ + return *mRenderTaskList; +} + +Dali::Layer Scene::GetRootLayer() const +{ + return Dali::Layer( mRootLayer.Get() ); +} + +LayerList& Scene::GetLayerList() const +{ + return *mLayerList; +} + +uint32_t Scene::GetLayerCount() const +{ + return mLayerList->GetLayerCount(); +} + +Dali::Layer Scene::GetLayer( uint32_t depth ) const +{ + return Dali::Layer(mLayerList->GetLayer( depth )); +} + +CameraActor& Scene::GetDefaultCameraActor() +{ + return *mDefaultCamera; +} + +Actor& Scene::GetDefaultRootActor() +{ + return *mRootLayer; +} + +void Scene::SetSurface( Integration::RenderSurface& surface ) +{ + mSurface = &surface; + if ( mSurface ) + { + mSurfaceSize.width = static_cast( mSurface->GetPositionSize().width ); + mSurfaceSize.height = static_cast( mSurface->GetPositionSize().height ); + + mSize.width = mSurfaceSize.width; + mSize.height = mSurfaceSize.height; + + // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position. + mDefaultCamera->SetPerspectiveProjection( mSurfaceSize ); + + mRootLayer->SetSize( mSize.width, mSize.height ); + + ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal(); + SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager(); + SetDefaultSurfaceRectMessage( updateManager, Rect( 0, 0, static_cast( mSurfaceSize.width ), static_cast( mSurfaceSize.height ) ) ); // truncated + + RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask( 0u ); + + // if single render task to screen then set its viewport parameters + if( 1 == mRenderTaskList->GetTaskCount() ) + { + if( !defaultRenderTask->GetTargetFrameBuffer() ) + { + defaultRenderTask->SetViewport( Viewport( 0, 0, static_cast( mSurfaceSize.width ), static_cast( mSurfaceSize.height ) ) ); // truncated + } + } + + mFrameBuffer = Dali::Internal::FrameBuffer::New( surface, Dali::FrameBuffer::Attachment::NONE ); + defaultRenderTask->SetFrameBuffer( mFrameBuffer ); + } +} + +Integration::RenderSurface* Scene::GetSurface() const +{ + return mSurface; +} + +void Scene::RequestRebuildDepthTree() +{ + mDepthTreeDirty = true; +} + +void Scene::RebuildDepthTree() +{ + // If the depth tree needs rebuilding, do it in this frame only. + if( mDepthTreeDirty ) + { + ActorPtr actor( mRootLayer.Get() ); + actor->RebuildDepthTree(); + mDepthTreeDirty = false; + } +} + +void Scene::SetBackgroundColor(Vector4 color) +{ + if( mSurface ) + { + mSurface->SetBackgroundColor( color ); + } +} + +Vector4 Scene::GetBackgroundColor() const +{ + return mSurface ? mSurface->GetBackgroundColor() : DEFAULT_BACKGROUND_COLOR; +} + + +} // Internal + +} // Dali diff --git a/dali/internal/event/common/scene-impl.h b/dali/internal/event/common/scene-impl.h new file mode 100644 index 000000000..1140b6a84 --- /dev/null +++ b/dali/internal/event/common/scene-impl.h @@ -0,0 +1,224 @@ +#ifndef DALI_INTERNAL_SCENE_H +#define DALI_INTERNAL_SCENE_H + +/* + * Copyright (c) 2019 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 +#include +#include +#include +#include +#include +#include + +namespace Dali +{ + +namespace Internal +{ + +class Layer; +class LayerList; +class CameraActor; +class RenderTaskList; +class FrameBuffer; + +using FrameBufferPtr = IntrusivePtr; +using ScenePtr = IntrusivePtr; + +/** + * @brief Scene creates a "world" that can be bound to a surface for rendering. + */ +class Scene : public BaseObject, public RenderTaskDefaults +{ + +public: + + /** + * @copydoc Dali::Integration::Scene::New + */ + static ScenePtr New( Size size ); + + /** + * virtual destructor + */ + virtual ~Scene(); + + /** + * @copydoc Dali::Integration::Scene::Add + */ + void Add(Actor& actor); + + /** + * @copydoc Dali::Integration::Scene::Remove + */ + void Remove(Actor& actor); + + /** + * @copydoc Dali::Integration::Scene::GetSize + */ + Size GetSize() const; + + /** + * @copydoc Dali::Integration::Scene::SetDpi + */ + void SetDpi( Vector2 dpi ); + + /** + * @copydoc Dali::Integration::Scene::GetDpi + */ + Vector2 GetDpi() const; + + /** + * @copydoc Dali::Integration::Scene::GetRenderTaskList + */ + RenderTaskList& GetRenderTaskList() const; + + /** + * @copydoc Dali::Integration::Scene::GetRootLayer + */ + Dali::Layer GetRootLayer() const; + + /** + * @copydoc Dali::Integration::Scene::GetLayerCount + */ + uint32_t GetLayerCount() const; + + /** + * @copydoc Dali::Integration::Scene::GetLayer + */ + Dali::Layer GetLayer(uint32_t depth) const; + + /** + * @copydoc Dali::Integration::Scene::SetSurface + */ + void SetSurface( Integration::RenderSurface& surface ); + + /** + * Retrieve the render surface the scene is binded to. + * @return The render surface. + */ + Integration::RenderSurface* GetSurface() const; + + /** + * Retrieve the ordered list of on-stage layers. + * @return The layer-list. + */ + LayerList& GetLayerList() const; + + /** + * Request that the depth tree is rebuilt + */ + void RequestRebuildDepthTree(); + + /** + * Rebuilds the depth tree at the end of the event frame if + * it was requested this frame. + */ + void RebuildDepthTree(); + + /** + * @brief Sets the background color of the render surface. + * @param[in] color The new background color + */ + void SetBackgroundColor(Vector4 color); + + /** + * @brief Gets the background color of the render surface. + * @return The background color + */ + Vector4 GetBackgroundColor() const; + +public: + + /** + * From RenderTaskDefaults; retrieve the default root actor. + * @return The default root actor. + */ + virtual Actor& GetDefaultRootActor(); + + /** + * From RenderTaskDefaults; retrieve the default camera actor. + * @return The default camera actor. + */ + virtual CameraActor& GetDefaultCameraActor(); + +private: + + // Constructor + Scene( Size size ); + + /** + * Second-phase constructor. + */ + void Initialize(); + + // Undefined + Scene(const Scene&) = delete; + + // Undefined + Scene& operator=(const Scene& rhs) = delete; + +private: + + Integration::RenderSurface* mSurface; + + // The scene-size may be different with the surface-size + Size mSize; + Size mSurfaceSize; + + Vector2 mDpi; + + LayerPtr mRootLayer; + + // Ordered list of currently on-stage layers + OwnerPointer mLayerList; + + IntrusivePtr mDefaultCamera; + + // The list of render-tasks + IntrusivePtr mRenderTaskList; + + // The frame buffer + FrameBufferPtr mFrameBuffer; + + bool mDepthTreeDirty:1; ///< True if the depth tree needs recalculating +}; + +} // Internal + +// Get impl of handle +inline Internal::Scene& GetImplementation(Dali::Integration::Scene& scene) +{ + DALI_ASSERT_ALWAYS( scene && "Scene handle is empty" ); + Dali::RefObject& object = scene.GetBaseObject(); + return static_cast(object); +} + +inline const Internal::Scene& GetImplementation(const Dali::Integration::Scene& scene) +{ + DALI_ASSERT_ALWAYS( scene && "Scene handle is empty" ); + const Dali::RefObject& object = scene.GetBaseObject(); + return static_cast(object); +} + +} // Dali + +#endif // DALI_INTERNAL_SCENE_H diff --git a/dali/internal/event/common/stage-impl.cpp b/dali/internal/event/common/stage-impl.cpp index 8294cf85a..54201e15f 100644 --- a/dali/internal/event/common/stage-impl.cpp +++ b/dali/internal/event/common/stage-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -85,61 +85,15 @@ SignalConnectorType signalConnector9( mType, SIGNAL_TOUCH, & } // unnamed namespace -StagePtr Stage::New( AnimationPlaylist& playlist, - PropertyNotificationManager& propertyNotificationManager, - SceneGraph::UpdateManager& updateManager, - NotificationManager& notificationManager, - Integration::RenderController& renderController ) +StagePtr Stage::New( SceneGraph::UpdateManager& updateManager ) { - return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager, renderController ) ); + return StagePtr( new Stage( updateManager ) ); } -void Stage::Initialize( bool renderToFbo ) +void Stage::Initialize( Scene& scene ) { - mRenderToFbo = renderToFbo; - mObjectRegistry = ObjectRegistry::New(); - - // Create the ordered list of layers - mLayerList = LayerList::New( mUpdateManager ); - - // The stage owns the default layer - mRootLayer = Layer::NewRoot( *mLayerList, mUpdateManager ); - mRootLayer->SetName("RootLayer"); - // The root layer needs to have a fixed resize policy (as opposed to the default USE_NATURAL_SIZE). - // This stops actors parented to the stage having their relayout requests propagating - // up to the root layer, and down through other children unnecessarily. - mRootLayer->SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS ); - - // Create the default camera actor first; this is needed by the RenderTaskList - CreateDefaultCameraActor(); - - // Create the list of render-tasks - mRenderTaskList = RenderTaskList::New(); - - // Create the default render-task (don't need the returned handle) - mRenderTaskList->CreateTask( mRootLayer.Get(), mDefaultCamera.Get() ); -} - -void Stage::Uninitialize() -{ - if( mDefaultCamera ) - { - // its enough to release the handle so the object is released - // don't need to remove it from root actor as root actor will delete the object - mDefaultCamera.Reset(); - } - - if( mRootLayer ) - { - // we are closing down so just delete the root, no point emit disconnect - // signals or send messages to update - mRootLayer.Reset(); - } - - if( mRenderTaskList ) - { - mRenderTaskList.Reset(); - } + mScene = &scene; + mScene->SetBackgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ); } StagePtr Stage::GetCurrent() @@ -161,182 +115,78 @@ bool Stage::IsInstalled() ObjectRegistry& Stage::GetObjectRegistry() { - return *mObjectRegistry; -} - -void Stage::RegisterObject( Dali::BaseObject* object ) -{ - mObjectRegistry->RegisterObject( object ); -} - -void Stage::UnregisterObject( Dali::BaseObject* object ) -{ - mObjectRegistry->UnregisterObject( object ); + return ThreadLocalStorage::Get().GetObjectRegistry(); } Layer& Stage::GetRootActor() { - return *mRootLayer; -} - -AnimationPlaylist& Stage::GetAnimationPlaylist() -{ - return mAnimationPlaylist; -} - -PropertyNotificationManager& Stage::GetPropertyNotificationManager() -{ - return mPropertyNotificationManager; + Dali::Layer rootLayer = GetRootLayer(); + return GetImplementation( rootLayer ); } void Stage::Add( Actor& actor ) { - mRootLayer->Add( actor ); + mScene->Add( actor ); } void Stage::Remove( Actor& actor ) { - mRootLayer->Remove( actor ); -} - -void Stage::SurfaceResized( float width, float height ) -{ - if( ( fabsf( width - mSurfaceSize.width ) > Math::MACHINE_EPSILON_1000 ) || ( fabsf( height - mSurfaceSize.height ) > Math::MACHINE_EPSILON_1000 ) ) - { - mSurfaceSize.width = width; - mSurfaceSize.height = height; - - // Internally we want to report the actual size of the stage. - mSize.width = width; - mSize.height = height - static_cast( mTopMargin ); - - // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position. - mDefaultCamera->SetPerspectiveProjection( mSurfaceSize ); - - // Adjust the camera height to allow for top-margin - SetDefaultCameraPosition(); - - mRootLayer->SetSize( mSize.width, mSize.height ); - - SetDefaultSurfaceRectMessage( mUpdateManager, Rect( 0, 0, static_cast( width ), static_cast( height ) ) ); // truncated - - // if single render task to screen then set its viewport parameters - if( 1 == mRenderTaskList->GetTaskCount() ) - { - RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask( 0u ); - - if(!defaultRenderTask->GetTargetFrameBuffer()) - { - defaultRenderTask->SetViewport( Viewport( 0, 0, static_cast( width ), static_cast( height ) ) ); // truncated - } - } - - if( mRenderToFbo ) - { - Dali::FrameBuffer frameBuffer = Dali::FrameBuffer::New( static_cast( width ), static_cast( height ), Dali::FrameBuffer::Attachment::NONE ); - Dali::Texture texture = Dali::Texture::New( Dali::TextureType::TEXTURE_2D, Dali::Pixel::RGB888, static_cast( width ), static_cast( height ) ); - frameBuffer.AttachColorTexture( texture ); - - RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask( 0u ); - defaultRenderTask->SetFrameBuffer( &GetImplementation( frameBuffer ) ); - } - } + mScene->Remove( actor ); } Vector2 Stage::GetSize() const { - return mSize; -} - -void Stage::SetTopMargin( uint32_t margin ) -{ - if (mTopMargin == margin) - { - return; - } - mTopMargin = margin; - - mSize.width = mSurfaceSize.width; - mSize.height = mSurfaceSize.height - static_cast( mTopMargin ); - - // Adjust the camera height to allow for top-margin - SetDefaultCameraPosition(); - - mRootLayer->SetSize( mSize.width, mSize.height ); + return mScene->GetSize(); } RenderTaskList& Stage::GetRenderTaskList() const { - return *mRenderTaskList; -} - -void Stage::CreateDefaultCameraActor() -{ - // The default camera attributes and position is such that - // children of the default layer, can be positioned at (0,0) and - // be at the top-left of the viewport. - mDefaultCamera = CameraActor::New( Size::ZERO ); - mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER); - Add(*(mDefaultCamera.Get())); -} - -void Stage::SetDefaultCameraPosition() -{ - mDefaultCamera->SetY( -(static_cast(mTopMargin) * 0.5f) ); + return mScene->GetRenderTaskList(); } Actor& Stage::GetDefaultRootActor() { - return *mRootLayer; + return mScene->GetDefaultRootActor(); } CameraActor& Stage::GetDefaultCameraActor() { - return *mDefaultCamera; + return mScene->GetDefaultCameraActor(); } uint32_t Stage::GetLayerCount() const { - return mLayerList->GetLayerCount(); + return mScene->GetLayerCount(); } Dali::Layer Stage::GetLayer( uint32_t depth ) const { - return Dali::Layer(mLayerList->GetLayer( depth )); + return mScene->GetLayer( depth ); } Dali::Layer Stage::GetRootLayer() const { - return Dali::Layer( mRootLayer.Get() ); + return mScene->GetRootLayer(); } LayerList& Stage::GetLayerList() { - return *mLayerList; + return mScene->GetLayerList(); } void Stage::SetBackgroundColor(Vector4 color) { - // Cache for public GetBackgroundColor() - mBackgroundColor = color; - - // Send message to change color in next frame - SetBackgroundColorMessage( mUpdateManager, color ); + mScene->SetBackgroundColor( color ); } Vector4 Stage::GetBackgroundColor() const { - return mBackgroundColor; + return mScene->GetBackgroundColor(); } Vector2 Stage::GetDpi() const { - return mDpi; -} - -void Stage::SetDpi(Vector2 dpi) -{ - mDpi = dpi; + return mScene->GetDpi(); } void Stage::KeepRendering( float durationSeconds ) @@ -520,42 +370,8 @@ void Stage::NotifyContextRegained() mContextRegainedSignal.Emit(); } - -void Stage::RequestRebuildDepthTree() -{ - DALI_LOG_INFO(gLogFilter, Debug::General, "RequestRebuildDepthTree()\n"); - mDepthTreeDirty = true; -} - -void Stage::RebuildDepthTree() -{ - // If the depth tree needs rebuilding, do it in this frame only. - if( mDepthTreeDirty ) - { - DALI_LOG_INFO(gLogFilter, Debug::Concise, "RebuildDepthTree() dirty:T\n"); - - ActorPtr actor( mRootLayer.Get() ); - actor->RebuildDepthTree(); - mDepthTreeDirty = false; - } -} - - -Stage::Stage( AnimationPlaylist& playlist, - PropertyNotificationManager& propertyNotificationManager, - SceneGraph::UpdateManager& updateManager, - NotificationManager& notificationManager, - Integration::RenderController& renderController ) -: mAnimationPlaylist( playlist ), - mPropertyNotificationManager( propertyNotificationManager ), - mUpdateManager( updateManager ), - mNotificationManager( notificationManager ), - mRenderController( renderController ), - mSize( Vector2::ZERO ), - mSurfaceSize( Vector2::ZERO ), - mBackgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ), - mTopMargin( 0 ), - mDpi( Vector2::ZERO ), +Stage::Stage( SceneGraph::UpdateManager& updateManager ) +: mUpdateManager( updateManager ), mKeyEventSignal(), mKeyEventGeneratedSignal(), mEventProcessingFinishedSignal(), @@ -565,43 +381,8 @@ Stage::Stage( AnimationPlaylist& playlist, mContextLostSignal(), mContextRegainedSignal(), mSceneCreatedSignal(), - mRenderingBehavior( DevelStage::Rendering::IF_REQUIRED ), - mDepthTreeDirty( false ), - mForceNextUpdate( false ), - mRenderToFbo( false ) -{ -} - -SceneGraph::UpdateManager& Stage::GetUpdateManager() -{ - return mUpdateManager; -} - -Integration::RenderController& Stage::GetRenderController() -{ - return mRenderController; -} - -uint32_t* Stage::ReserveMessageSlot( uint32_t size, bool updateScene ) -{ - return mUpdateManager.ReserveMessageSlot( size, updateScene ); -} - -BufferIndex Stage::GetEventBufferIndex() const -{ - return mUpdateManager.GetEventBufferIndex(); -} - -void Stage::ForceNextUpdate() -{ - mForceNextUpdate = true; -} - -bool Stage::IsNextUpdateForced() + mRenderingBehavior( DevelStage::Rendering::IF_REQUIRED ) { - bool nextUpdateForced = mForceNextUpdate; - mForceNextUpdate = false; - return nextUpdateForced; } Stage::~Stage() diff --git a/dali/internal/event/common/stage-impl.h b/dali/internal/event/common/stage-impl.h index 493c34682..1f524318b 100644 --- a/dali/internal/event/common/stage-impl.h +++ b/dali/internal/event/common/stage-impl.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_STAGE_H /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -60,38 +60,26 @@ class Layer; class LayerList; class CameraActor; class RenderTaskList; +class Scene; /** * Implementation of Stage */ -class Stage : public BaseObject, public RenderTaskDefaults, public Integration::ContextNotifierInterface, public EventThreadServices +class Stage : public BaseObject, public RenderTaskDefaults, public Integration::ContextNotifierInterface { public: /** * Create the stage - * @param[in] playlist for animations - * @param[in] propertyNotificationManager * @param[in] updateManager - * @param[in] notificationManager - * @param[in] renderController */ - static StagePtr New( AnimationPlaylist& playlist, - PropertyNotificationManager& propertyNotificationManager, - SceneGraph::UpdateManager& updateManager, - NotificationManager& notificationManager, - Integration::RenderController& renderController ); + static StagePtr New( SceneGraph::UpdateManager& updateManager ); /** * Initialize the stage. - * @param[in] renderToFbo Whether to render into a Frame Buffer Object. + * @param[in] scene The default scene (for main window). */ - void Initialize( bool renderToFbo ); - - /** - * Uninitialize the stage. - */ - void Uninitialize(); + void Initialize( Scene& scene ); /** * @copydoc Dali::Stage::GetCurrent() @@ -115,18 +103,6 @@ public: */ Layer& GetRootActor(); - /** - * Returns the animation playlist. - * @return reference to the animation playlist. - */ - AnimationPlaylist& GetAnimationPlaylist(); - - /** - * Returns the property notification manager. - * @return reference to the property notification manager. - */ - PropertyNotificationManager& GetPropertyNotificationManager(); - // Root actor accessors /** @@ -139,22 +115,6 @@ public: */ void Remove( Actor& actor ); - /** - * Used to calculate the size of the stage and indirectly, the root actor. - * @param [in] width The new surface width. - * @param [in] height The new surface height. - */ - void SurfaceResized( float width, float height ); - - /** - * Sets the top margin size. - * Available stage size is reduced by this size. - * The stage is located below the size at the top of the display - * initial size is zero before it is assigned - * @param[in] margin margin size - */ - void SetTopMargin( uint32_t margin ); - /** * Returns the size of the Stage in pixels as a Vector. * The x component will be the width of the Stage in pixels @@ -168,16 +128,6 @@ public: */ RenderTaskList& GetRenderTaskList() const; - /** - * Create a default camera actor - */ - void CreateDefaultCameraActor(); - - /** - * Set position of default camera for current stage size - */ - void SetDefaultCameraPosition(); - /** * From RenderTaskDefaults; retrieve the default root actor. * @return The default root actor. @@ -213,27 +163,6 @@ public: */ LayerList& GetLayerList(); - // Keyboard stuff - - /** - * As one virtual keyboard per stage, the stage will hold a pointer to the Actor currently - * set to receive keyboard input. - * @param[in] actor to receive keyboard input - */ - void SetKeyboardFocusActor( Actor* actor ); - - /** - * Get the actor that is currently set to receive keyboard inputs - * @return Pointer to the actor set to receive keyboard inputs. - */ - Actor* GetKeyboardFocusActor() const; - - /** - * Removes the given actor from keyboard focus so it will no longer receive key events from keyboard. - * @param [in] actor which should be removed from focus. - */ - void RemoveActorFromKeyFocus( Actor* actor ); - // Misc /** @@ -251,17 +180,6 @@ public: */ Vector2 GetDpi() const; - /** - * Sets horizontal and vertical pixels per inch value that is used by the display - * @param[in] dpi Horizontal and vertical dpi value - */ - void SetDpi( Vector2 dpi ); - - NotificationManager& GetNotificationManager() - { - return mNotificationManager; - } - /** * @copydoc Dali::Stage::KeepRendering() */ @@ -393,69 +311,12 @@ private: // Implementation of ContextNotificationInterface: */ virtual void NotifyContextRegained(); -public: // Implementation of EventThreadServices - - /** - * @copydoc EventThreadServices::RegisterObject - */ - virtual void RegisterObject( BaseObject* object); - - /** - * @copydoc EventThreadServices::UnregisterObject - */ - virtual void UnregisterObject( BaseObject* object); - - /** - * @copydoc EventThreadServices::GetUpdateManager - */ - virtual SceneGraph::UpdateManager& GetUpdateManager(); - - /** - * @copydoc EventThreadServices::GetRenderController - */ - virtual Integration::RenderController& GetRenderController(); - - /** - * @copydoc EventThreadServices::ReserveMessageSlot - */ - virtual uint32_t* ReserveMessageSlot( uint32_t size, bool updateScene ); - - /** - * @copydoc EventThreadServices::GetEventBufferIndex - */ - virtual BufferIndex GetEventBufferIndex() const; - - /** - * @copydoc EventThreadServices::ForceNextUpdate - */ - virtual void ForceNextUpdate(); - - /** - * @copydoc EventThreadServices::IsNextUpdateForced - */ - virtual bool IsNextUpdateForced(); - - /** - * Request that the depth tree is rebuilt - */ - void RequestRebuildDepthTree(); - - /** - * Rebuilds the depth tree at the end of the event frame if - * it was requested this frame. - */ - void RebuildDepthTree(); - private: /** * Protected constructor; see also Stage::New() */ - Stage( AnimationPlaylist& playlist, - PropertyNotificationManager& propertyNotificationManager, - SceneGraph::UpdateManager& updateManager, - NotificationManager& notificationManager, - Integration::RenderController& renderController ); + Stage( SceneGraph::UpdateManager& updateManager ); /** * A reference counted object may only be deleted by calling Unreference() @@ -464,39 +325,9 @@ private: private: - // For 'Fire and forget' animation support - AnimationPlaylist& mAnimationPlaylist; - - PropertyNotificationManager& mPropertyNotificationManager; - SceneGraph::UpdateManager& mUpdateManager; - NotificationManager& mNotificationManager; - - Integration::RenderController& mRenderController; - - // The stage-size may be less than surface-size (reduced by top-margin) - Vector2 mSize; - Vector2 mSurfaceSize; - - // Cached for public GetBackgroundColor() - Vector4 mBackgroundColor; - - LayerPtr mRootLayer; - - // Ordered list of currently on-stage layers - OwnerPointer mLayerList; - - IntrusivePtr mDefaultCamera; - - uint32_t mTopMargin; - Vector2 mDpi; - - // The object registry - ObjectRegistryPtr mObjectRegistry; - - // The list of render-tasks - IntrusivePtr mRenderTaskList; + IntrusivePtr mScene; // The key event signal Dali::Stage::KeyEventSignalType mKeyEventSignal; @@ -518,10 +349,6 @@ private: Dali::Stage::SceneCreatedSignalType mSceneCreatedSignal; DevelStage::Rendering mRenderingBehavior; ///< The rendering behavior - - bool mDepthTreeDirty:1; ///< True if the depth tree needs recalculating - bool mForceNextUpdate:1; ///< True if the next rendering is really required. - bool mRenderToFbo:1; ///< Whether to render to a Frame Buffer Object. }; } // namespace Internal diff --git a/dali/internal/event/common/thread-local-storage.cpp b/dali/internal/event/common/thread-local-storage.cpp index 559b83356..1eab33213 100644 --- a/dali/internal/event/common/thread-local-storage.cpp +++ b/dali/internal/event/common/thread-local-storage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -21,6 +21,7 @@ // INTERNAL INCLUDES #include #include +#include namespace Dali { @@ -103,6 +104,36 @@ RelayoutController& ThreadLocalStorage::GetRelayoutController() return mCore->GetRelayoutController(); } +ObjectRegistry& ThreadLocalStorage::GetObjectRegistry() +{ + return mCore->GetObjectRegistry(); +} + +EventThreadServices& ThreadLocalStorage::GetEventThreadServices() +{ + return mCore->GetEventThreadServices(); +} + +PropertyNotificationManager& ThreadLocalStorage::GetPropertyNotificationManager() +{ + return mCore->GetPropertyNotificationManager(); +} + +AnimationPlaylist& ThreadLocalStorage::GetAnimationPlaylist() +{ + return mCore->GetAnimationPlaylist(); +} + +void ThreadLocalStorage::AddScene( Scene* scene ) +{ + mCore->AddScene( scene ); +} + +void ThreadLocalStorage::RemoveScene( Scene* scene ) +{ + mCore->RemoveScene( scene ); +} + } // namespace Internal } // namespace Dali diff --git a/dali/internal/event/common/thread-local-storage.h b/dali/internal/event/common/thread-local-storage.h index 95b6c30c6..0e6e4009d 100644 --- a/dali/internal/event/common/thread-local-storage.h +++ b/dali/internal/event/common/thread-local-storage.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_THREAD_LOCAL_STORAGE_H__ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include namespace Dali { @@ -39,6 +40,8 @@ class NotificationManager; class ShaderFactory; class GestureEventProcessor; class RelayoutController; +class ObjectRegistry; +class EventThreadServices; namespace SceneGraph { @@ -131,6 +134,44 @@ public: */ RelayoutController& GetRelayoutController(); + /** + * Returns the Object registry. + * @return A reference to the Object registry + */ + ObjectRegistry& GetObjectRegistry(); + + /** + * @brief Gets the event thread services. + * @return A reference to the event thread services + */ + EventThreadServices& GetEventThreadServices(); + + /** + * @brief Gets the property notification manager. + * @return A reference to the property notification manager + */ + PropertyNotificationManager& GetPropertyNotificationManager(); + + /** + * @brief Gets the animation play list. + * @return A reference to the animation play list + */ + AnimationPlaylist& GetAnimationPlaylist(); + + /** + * Add a Scene to the Core. + * This is only used by the Scene to add itself to the core when the Scene is created. + * @param[in] scene The Scene. + */ + void AddScene( Scene* scene ); + + /** + * Remove a Scene from the Core. + * This is only used by the Scene to remove itself from the core when the Scene is destroyed. + * @param[in] scene The Scene. + */ + void RemoveScene( Scene* scene ); + private: Core* mCore; ///< reference to core diff --git a/dali/internal/event/render-tasks/render-task-impl.cpp b/dali/internal/event/render-tasks/render-task-impl.cpp index 14bc16b06..aeec93fa3 100644 --- a/dali/internal/event/render-tasks/render-task-impl.cpp +++ b/dali/internal/event/render-tasks/render-task-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -32,7 +32,6 @@ #include #include #include -#include #include #if defined(DEBUG_ENABLED) @@ -71,14 +70,17 @@ SignalConnectorType signalConnector1( mType, SIGNAL_FINISHED, &RenderTask::DoCon } // Unnamed namespace -RenderTaskPtr RenderTask::New( Actor* sourceActor, CameraActor* cameraActor, SceneGraph::RenderTaskList& parentSceneObject ) +RenderTaskPtr RenderTask::New( Actor* sourceActor, CameraActor* cameraActor, RenderTaskList& renderTaskList ) { // create scene object first so it's guaranteed to exist for the event side auto sceneObject = SceneGraph::RenderTask::New(); - OwnerPointer< SceneGraph::RenderTask > transferOwnership( sceneObject ); + // pass the pointer to base for message passing - RenderTaskPtr task( new RenderTask( sceneObject ) ); + RenderTaskPtr task( new RenderTask( sceneObject, renderTaskList ) ); + // transfer scene object ownership to update manager + const SceneGraph::RenderTaskList& parentSceneObject = renderTaskList.GetSceneObject(); + OwnerPointer< SceneGraph::RenderTask > transferOwnership( sceneObject ); AddTaskMessage( task->GetEventThreadServices(), parentSceneObject, transferOwnership ); // Set the default source & camera actors @@ -100,12 +102,9 @@ void RenderTask::SetSourceActor( Actor* actor ) { SetSourceNodeMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), nullptr ); } + // set the actor on exclusive container for hit testing - const Stage* stage = Stage::GetCurrent(); - if ( stage ) - { - stage->GetRenderTaskList().SetExclusive( this, mExclusive ); - } + mRenderTaskList.SetExclusive( this, mExclusive ); } Actor* RenderTask::GetSourceActor() const @@ -119,11 +118,7 @@ void RenderTask::SetExclusive( bool exclusive ) { mExclusive = exclusive; - const Stage* stage = Stage::GetCurrent(); - if ( stage ) - { - stage->GetRenderTaskList().SetExclusive( this, exclusive ); - } + mRenderTaskList.SetExclusive( this, exclusive ); // scene object is being used in a separate thread; queue a message to set the value SetExclusiveMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), mExclusive ); @@ -156,6 +151,9 @@ void RenderTask::SetCameraActor( CameraActor* cameraActor ) { SetCameraMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), nullptr, nullptr ); } + + // set the actor on exclusive container for hit testing + mRenderTaskList.SetExclusive( this, mExclusive ); } CameraActor* RenderTask::GetCameraActor() const @@ -521,7 +519,6 @@ Property::Value RenderTask::GetDefaultProperty(Property::Index index) const switch ( index ) { - case Dali::RenderTask::Property::VIEWPORT_POSITION: { value = mViewportPosition; @@ -559,7 +556,6 @@ Property::Value RenderTask::GetDefaultPropertyCurrentValue( Property::Index inde switch ( index ) { - case Dali::RenderTask::Property::VIEWPORT_POSITION: { value = GetCurrentViewportPosition(); @@ -747,11 +743,12 @@ bool RenderTask::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface return connected; } -RenderTask::RenderTask( const SceneGraph::RenderTask* sceneObject ) +RenderTask::RenderTask( const SceneGraph::RenderTask* sceneObject, RenderTaskList& renderTaskList ) : Object( sceneObject ), mSourceActor( nullptr ), mCameraActor( nullptr ), mInputMappingActor(), + mRenderTaskList( renderTaskList ), mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ), mViewportPosition( Vector2::ZERO ), mViewportSize( Vector2::ZERO ), diff --git a/dali/internal/event/render-tasks/render-task-impl.h b/dali/internal/event/render-tasks/render-task-impl.h index de111d010..45e59eabc 100644 --- a/dali/internal/event/render-tasks/render-task-impl.h +++ b/dali/internal/event/render-tasks/render-task-impl.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_RENDER_TASK_H__ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -25,6 +25,7 @@ #include #include #include +#include namespace Dali { @@ -35,6 +36,7 @@ namespace Internal class Actor; class CameraActor; class EventThreadServices; +class RenderTaskList; namespace SceneGraph { @@ -53,8 +55,13 @@ public: /** * Creates a new RenderTask. + * + * @param[in] sourceActor The source actor. + * @param[in] cameraActor The camera actor. + * @param[in] renderTaskList The render task list. + * @return The created render task */ - static RenderTaskPtr New( Actor* sourceActor, CameraActor* cameraActor, SceneGraph::RenderTaskList& parentSceneObject ); + static RenderTaskPtr New( Actor* sourceActor, CameraActor* cameraActor, RenderTaskList& renderTaskList ); /** * @copydoc Dali::RenderTask::SetSourceActor() @@ -319,9 +326,10 @@ protected: /** * Constructor. * - * @param sceneObject the scene graph object + * @param[in] sceneObject The scene graph object + * @param[in] renderTaskList The render task list */ - RenderTask( const SceneGraph::RenderTask* sceneObject ); + RenderTask( const SceneGraph::RenderTask* sceneObject, RenderTaskList& renderTaskList ); /** * A reference counted object may only be deleted by calling Unreference() @@ -339,6 +347,7 @@ private: Actor* mSourceActor; ///< Source actor, we cannot keep the actor alive so raw pointer. CameraActor* mCameraActor; ///< Camera actor, we cannot keep the actor alive so raw pointer. WeakHandle mInputMappingActor; /// used to mapping screen to frame buffer coordinate, not kept alive by rendertask + RenderTaskList& mRenderTaskList; ///< The render task list Vector4 mClearColor; ///< Optional clear color diff --git a/dali/internal/event/render-tasks/render-task-list-impl.cpp b/dali/internal/event/render-tasks/render-task-list-impl.cpp index c3a40d6dc..eb4bbf644 100644 --- a/dali/internal/event/render-tasks/render-task-list-impl.cpp +++ b/dali/internal/event/render-tasks/render-task-list-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -21,7 +21,6 @@ // INTERNAL INCLUDES #include #include -#include #include #include #include @@ -60,7 +59,7 @@ RenderTaskPtr RenderTaskList::CreateTask() RenderTaskPtr RenderTaskList::CreateTask( Actor* sourceActor, CameraActor* cameraActor) { - RenderTaskPtr task = RenderTask::New( sourceActor, cameraActor, *mSceneObject ); + RenderTaskPtr task = RenderTask::New( sourceActor, cameraActor, *this ); mTasks.push_back( task ); @@ -135,7 +134,7 @@ void RenderTaskList::SetExclusive( RenderTask* task, bool exclusive ) } RenderTaskList::RenderTaskList() -: mEventThreadServices( *Stage::GetCurrent() ), +: mEventThreadServices( EventThreadServices::Get() ), mDefaults( *Stage::GetCurrent() ), mSceneObject( nullptr ) { @@ -197,6 +196,11 @@ void RenderTaskList::RecoverFromContextLoss() } } +const SceneGraph::RenderTaskList& RenderTaskList::GetSceneObject() const +{ + return *mSceneObject; +} + } // namespace Internal } // namespace Dali diff --git a/dali/internal/event/render-tasks/render-task-list-impl.h b/dali/internal/event/render-tasks/render-task-list-impl.h index 55e37e83c..9f203d81f 100644 --- a/dali/internal/event/render-tasks/render-task-list-impl.h +++ b/dali/internal/event/render-tasks/render-task-list-impl.h @@ -36,6 +36,7 @@ class RenderTaskDefaults; class Actor; class CameraActor; +using RenderTaskPtr = IntrusivePtr; class RenderTaskList; using RenderTaskListPtr = IntrusivePtr; @@ -139,6 +140,12 @@ public: */ void RecoverFromContextLoss(); + /** + * Retrieve the SceneGraph::RenderTaskList object. + * @return The RenderTaskList. + */ + const SceneGraph::RenderTaskList& GetSceneObject() const; + protected: /** diff --git a/dali/internal/event/rendering/frame-buffer-impl.cpp b/dali/internal/event/rendering/frame-buffer-impl.cpp index ccfc8d051..fd5f4bff6 100644 --- a/dali/internal/event/rendering/frame-buffer-impl.cpp +++ b/dali/internal/event/rendering/frame-buffer-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -20,8 +20,10 @@ // INTERNAL INCLUDES #include -#include #include +#include +#include +#include namespace Dali { @@ -35,6 +37,13 @@ FrameBufferPtr FrameBuffer::New( uint32_t width, uint32_t height, Mask attachmen return frameBuffer; } +FrameBufferPtr FrameBuffer::New( Dali::Integration::RenderSurface& renderSurface, Mask attachments ) +{ + Dali::PositionSize positionSize = renderSurface.GetPositionSize(); + FrameBufferPtr frameBuffer( new FrameBuffer( positionSize.width, positionSize.height, attachments ) ); + frameBuffer->Initialize( &renderSurface ); + return frameBuffer; +} Render::FrameBuffer* FrameBuffer::GetRenderObject() const { @@ -42,38 +51,58 @@ Render::FrameBuffer* FrameBuffer::GetRenderObject() const } FrameBuffer::FrameBuffer( uint32_t width, uint32_t height, Mask attachments ) -: mEventThreadServices( *Stage::GetCurrent() ), +: mEventThreadServices( EventThreadServices::Get() ), mRenderObject( NULL ), mColor( NULL ), mWidth( width ), mHeight( height ), - mAttachments( attachments ) + mAttachments( attachments ), + mIsSurfaceBacked( false ) { } -void FrameBuffer::Initialize() +void FrameBuffer::Initialize( Integration::RenderSurface* renderSurface ) { - mRenderObject = new Render::FrameBuffer( mWidth, mHeight, mAttachments ); + mIsSurfaceBacked = ( renderSurface != nullptr ); + + // If render surface backed, create a different scene object + // Make Render::FrameBuffer as a base class, and implement Render::TextureFrameBuffer & Render::WindowFrameBuffer + if ( mIsSurfaceBacked ) + { + mRenderObject = new Render::SurfaceFrameBuffer( renderSurface ); + } + else + { + mRenderObject = new Render::TextureFrameBuffer( mWidth, mHeight, mAttachments ); + } + AddFrameBuffer( mEventThreadServices.GetUpdateManager(), *mRenderObject ); } void FrameBuffer::AttachColorTexture( TexturePtr texture, uint32_t mipmapLevel, uint32_t layer ) { - if( ( texture->GetWidth() / ( 1u << mipmapLevel ) == mWidth ) && - ( texture->GetHeight() / ( 1u << mipmapLevel ) == mHeight ) ) + if ( mIsSurfaceBacked ) { - mColor = texture; - AttachColorTextureToFrameBuffer( mEventThreadServices.GetUpdateManager(), *mRenderObject, texture->GetRenderObject(), mipmapLevel, layer ); + DALI_LOG_ERROR( "Attempted to attach color texture to a render surface backed FrameBuffer \n" ); } else { - DALI_LOG_ERROR( "Failed to attach color texture to FrameBuffer: Size mismatch \n" ); + if( ( texture->GetWidth() / ( 1u << mipmapLevel ) == mWidth ) && + ( texture->GetHeight() / ( 1u << mipmapLevel ) == mHeight ) ) + { + mColor = texture; + AttachColorTextureToFrameBuffer( mEventThreadServices.GetUpdateManager(), *mRenderObject, texture->GetRenderObject(), mipmapLevel, layer ); + } + else + { + DALI_LOG_ERROR( "Failed to attach color texture to FrameBuffer: Size mismatch \n" ); + } } } Texture* FrameBuffer::GetColorTexture() { - return mColor.Get(); + return mIsSurfaceBacked ? nullptr : mColor.Get(); } FrameBuffer::~FrameBuffer() diff --git a/dali/internal/event/rendering/frame-buffer-impl.h b/dali/internal/event/rendering/frame-buffer-impl.h index 938919300..3531c0f14 100644 --- a/dali/internal/event/rendering/frame-buffer-impl.h +++ b/dali/internal/event/rendering/frame-buffer-impl.h @@ -28,6 +28,12 @@ namespace Dali { + +namespace Integration +{ +class RenderSurface; +} + namespace Internal { namespace Render @@ -54,6 +60,20 @@ public: */ static FrameBufferPtr New( uint32_t width, uint32_t height, Mask attachments ); + /** + * @brief Create a new FrameBuffer + * + * @param[in] renderSurface The render surface + * @param[in] attachments The attachments comprising the format of the FrameBuffer (bit-mask) + * @return A smart-pointer to the newly allocated Texture. + */ + static FrameBufferPtr New( Dali::Integration::RenderSurface& renderSurface, Mask attachments ); + + /** + * A reference counted object may only be deleted by calling Unreference() + */ + virtual ~FrameBuffer(); + /** * @brief Get the FrameBuffer render object * @@ -84,15 +104,10 @@ private: // implementation /** * Second stage initialization of the Texture */ - void Initialize(); + void Initialize( Integration::RenderSurface* renderSurface = nullptr ); protected: - /** - * A reference counted object may only be deleted by calling Unreference() - */ - virtual ~FrameBuffer(); - private: // unimplemented methods FrameBuffer() = delete; @@ -109,6 +124,8 @@ private: // data uint32_t mHeight; Mask mAttachments; ///< Bit-mask of type FrameBuffer::Attachment::Mask + bool mIsSurfaceBacked:1; + }; } // namespace Internal diff --git a/dali/internal/event/rendering/geometry-impl.cpp b/dali/internal/event/rendering/geometry-impl.cpp index 0897c08cb..57469e510 100644 --- a/dali/internal/event/rendering/geometry-impl.cpp +++ b/dali/internal/event/rendering/geometry-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -20,7 +20,7 @@ // INTERNAL INCLUDES #include -#include + #include namespace Dali @@ -88,7 +88,7 @@ const Render::Geometry* Geometry::GetRenderObject() const } Geometry::Geometry() -: mEventThreadServices( *Stage::GetCurrent() ), +: mEventThreadServices( EventThreadServices::Get() ), mRenderObject( NULL ), mType(Dali::Geometry::TRIANGLES) { diff --git a/dali/internal/event/rendering/sampler-impl.cpp b/dali/internal/event/rendering/sampler-impl.cpp index d6e8af0df..79d118553 100644 --- a/dali/internal/event/rendering/sampler-impl.cpp +++ b/dali/internal/event/rendering/sampler-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -58,7 +58,7 @@ Render::Sampler* Sampler::GetSamplerRenderObject() Sampler::Sampler() -:mEventThreadServices( *Stage::GetCurrent() ), +:mEventThreadServices( EventThreadServices::Get() ), mRenderObject( NULL ) { } diff --git a/dali/internal/event/rendering/texture-impl.cpp b/dali/internal/event/rendering/texture-impl.cpp index 3c3bbbdc9..3fb61f70d 100644 --- a/dali/internal/event/rendering/texture-impl.cpp +++ b/dali/internal/event/rendering/texture-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -50,7 +50,7 @@ Render::Texture* Texture::GetRenderObject() const } Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size ) -: mEventThreadServices( *Stage::GetCurrent() ), +: mEventThreadServices( EventThreadServices::Get() ), mRenderObject( NULL ), mNativeImage(), mSize( size ), @@ -60,7 +60,7 @@ Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions s } Texture::Texture( NativeImageInterfacePtr nativeImageInterface ) -: mEventThreadServices( *Stage::GetCurrent() ), +: mEventThreadServices( EventThreadServices::Get() ), mRenderObject( NULL ), mNativeImage( nativeImageInterface ), mSize( nativeImageInterface->GetWidth(), nativeImageInterface->GetHeight() ), diff --git a/dali/internal/event/rendering/texture-set-impl.cpp b/dali/internal/event/rendering/texture-set-impl.cpp index 349eaa65e..7c562e4db 100644 --- a/dali/internal/event/rendering/texture-set-impl.cpp +++ b/dali/internal/event/rendering/texture-set-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -20,7 +20,6 @@ // INTERNAL INCLUDES #include -#include #include #include @@ -136,7 +135,7 @@ const SceneGraph::TextureSet* TextureSet::GetTextureSetSceneObject() const } TextureSet::TextureSet() -:mEventThreadServices( *Stage::GetCurrent() ), +:mEventThreadServices( EventThreadServices::Get() ), mSceneObject( NULL ) { } diff --git a/dali/internal/event/size-negotiation/relayout-controller-impl.cpp b/dali/internal/event/size-negotiation/relayout-controller-impl.cpp index 35190fe8b..87d864533 100644 --- a/dali/internal/event/size-negotiation/relayout-controller-impl.cpp +++ b/dali/internal/event/size-negotiation/relayout-controller-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -90,6 +90,7 @@ void PrintHierarchy() if ( gLogFilter->IsEnabledFor( Debug::Verbose ) ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "---------- ROOT LAYER ----------\n" ); + PrintChildren( Stage::GetCurrent()->GetRootLayer(), 0 ); } } @@ -109,7 +110,6 @@ RelayoutController::RelayoutController( Integration::RenderController& controlle mRelayoutInfoAllocator(), mSlotDelegate( this ), mRelayoutStack( new MemoryPoolRelayoutContainer( mRelayoutInfoAllocator ) ), - mStageSize(), // zero initialized mRelayoutConnection( false ), mRelayoutFlag( false ), mEnabled( false ), @@ -130,17 +130,12 @@ RelayoutController* RelayoutController::Get() return &ThreadLocalStorage::Get().GetRelayoutController(); } -void RelayoutController::SetStageSize( uint32_t width, uint32_t height ) -{ - mStageSize.width = static_cast( width ); - mStageSize.height = static_cast( height ); -} - -void RelayoutController::QueueActor( Dali::Actor& actor, RelayoutContainer& actors, Vector2 size ) +void RelayoutController::QueueActor( Internal::Actor* actor, RelayoutContainer& actors, Vector2 size ) { - if( GetImplementation( actor ).RelayoutRequired() ) + if( actor && actor->RelayoutRequired() ) { - actors.Add( actor, size ); + Dali::Actor actorHandle = Dali::Actor( actor ); + actors.Add( actorHandle, size ); } } @@ -208,12 +203,6 @@ void RelayoutController::OnApplicationSceneCreated() // Open relayout controller to receive relayout requests mEnabled = true; - // Spread the dirty flag through whole tree - don't need to explicity - // add request on rootLayer as it will automatically be added below. - Dali::Stage stage = Dali::Stage::GetCurrent(); - Dali::Actor rootLayer = stage.GetRootLayer(); - RequestRelayoutTree( rootLayer ); - // Flag request for end of frame Request(); } @@ -374,7 +363,7 @@ void RelayoutController::PropagateFlags( Dali::Actor& actor, Dimension::Type dim void RelayoutController::AddRequest( Dali::Actor& actor ) { - BaseObject* actorPtr = &GetImplementation( actor ); + Internal::Actor* actorPtr = &GetImplementation( actor ); // Only add the rootActor if it is not already recorded bool found = false; @@ -395,7 +384,7 @@ void RelayoutController::AddRequest( Dali::Actor& actor ) void RelayoutController::RemoveRequest( Dali::Actor& actor ) { - BaseObject* actorPtr = &GetImplementation( actor ); + Internal::Actor* actorPtr = &GetImplementation( actor ); // Remove actor from dirty sub trees for( RawActorList::Iterator it = mDirtyLayoutSubTrees.Begin(), itEnd = mDirtyLayoutSubTrees.End(); it != itEnd; ++it ) @@ -414,8 +403,7 @@ void RelayoutController::Request() if( !mRelayoutConnection ) { - Dali::Stage stage = Dali::Stage::GetCurrent(); - stage.GetObjectRegistry().ObjectDestroyedSignal().Connect( mSlotDelegate, &RelayoutController::OnObjectDestroyed ); + ThreadLocalStorage::Get().GetObjectRegistry().ObjectDestroyedSignal().Connect( mSlotDelegate, &RelayoutController::OnObjectDestroyed ); mRelayoutConnection = true; } @@ -441,19 +429,16 @@ void RelayoutController::Relayout() // These controls are paired with the parent/stage size and added to the stack. for( RawActorList::Iterator it = mDirtyLayoutSubTrees.Begin(), itEnd = mDirtyLayoutSubTrees.End(); it != itEnd; ++it ) { - BaseObject* dirtyActor = *it; + Internal::Actor* dirtyActor = *it; // Need to test if actor is valid (could have been deleted and had the pointer cleared) if( dirtyActor ) { - // We know that BaseObject is a base class of Internal::Actor but need to instruct the compiler to do the cast - Dali::Actor actor = Dali::Actor( reinterpret_cast( dirtyActor ) ); - // Only negotiate actors that are on stage - if( actor.OnStage() ) + if( dirtyActor->OnStage() ) { - Dali::Actor parent = actor.GetParent(); - QueueActor( actor, *mRelayoutStack, ( parent ) ? Vector2( parent.GetTargetSize() ) : mStageSize ); + Internal::Actor* parent = dirtyActor->GetParent(); + QueueActor( dirtyActor, *mRelayoutStack, ( parent ) ? Vector2( parent->GetTargetSize() ) : dirtyActor->GetScene().GetSize() ); } } } diff --git a/dali/internal/event/size-negotiation/relayout-controller-impl.h b/dali/internal/event/size-negotiation/relayout-controller-impl.h index 543ae66ce..5f7fb1f96 100644 --- a/dali/internal/event/size-negotiation/relayout-controller-impl.h +++ b/dali/internal/event/size-negotiation/relayout-controller-impl.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H__ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -67,13 +67,6 @@ public: */ static RelayoutController* Get(); - /** - * Set the stage size - * @param width of the stage - * @param height of the stage - */ - void SetStageSize( uint32_t width, uint32_t height ); - /** * @brief Request to relayout the given actor and all sub-actors of it. * @@ -150,7 +143,7 @@ public: // CALLBACKS private: - typedef Dali::Vector< BaseObject* > RawActorList; + using RawActorList = Dali::Vector< Dali::Internal::Actor* >; /** * @brief Request for relayout. Relays out whole scene. @@ -194,7 +187,7 @@ private: * @param[in] actors The container to add the actor to * @param[in] size The size that this actor should be */ - void QueueActor( Dali::Actor& actor, RelayoutContainer& actors, Vector2 size ); + void QueueActor( Internal::Actor* actor, RelayoutContainer& actors, Vector2 size ); /** * @brief Find the given object in the list and null it out @@ -205,8 +198,8 @@ private: void FindAndZero( const RawActorList& list, const Dali::RefObject* object ); // Undefined - RelayoutController(const RelayoutController&); - RelayoutController& operator=(const RelayoutController&); + RelayoutController(const RelayoutController&) = delete; + RelayoutController& operator=(const RelayoutController&) = delete; private: @@ -218,7 +211,6 @@ private: RawActorList mDirtyLayoutSubTrees; ///< List of roots of sub trees that are dirty MemoryPoolRelayoutContainer* mRelayoutStack; ///< Stack for relayouting - Vector2 mStageSize; ///< size of the stage bool mRelayoutConnection : 1; ///< Whether EventProcessingFinishedSignal signal is connected. bool mRelayoutFlag : 1; ///< Relayout flag to avoid unnecessary calls bool mEnabled : 1; ///< Initially disabled. Must be enabled at some point. diff --git a/dali/internal/file.list b/dali/internal/file.list index 367a424a8..c007a0479 100644 --- a/dali/internal/file.list +++ b/dali/internal/file.list @@ -36,6 +36,7 @@ internal_src_files = \ $(internal_src_dir)/event/common/property-notification-impl.cpp \ $(internal_src_dir)/event/common/property-notification-manager.cpp \ $(internal_src_dir)/event/common/property-helper.cpp \ + $(internal_src_dir)/event/common/scene-impl.cpp \ $(internal_src_dir)/event/common/stage-impl.cpp \ $(internal_src_dir)/event/common/thread-local-storage.cpp \ $(internal_src_dir)/event/common/type-info-impl.cpp \ @@ -98,7 +99,8 @@ internal_src_files = \ $(internal_src_dir)/render/gl-resources/gl-call-debug.cpp \ $(internal_src_dir)/render/gl-resources/gpu-buffer.cpp \ $(internal_src_dir)/render/queue/render-queue.cpp \ - $(internal_src_dir)/render/renderers/render-frame-buffer.cpp \ + $(internal_src_dir)/render/renderers/render-texture-frame-buffer.cpp \ + $(internal_src_dir)/render/renderers/render-surface-frame-buffer.cpp \ $(internal_src_dir)/render/renderers/render-geometry.cpp \ $(internal_src_dir)/render/renderers/render-property-buffer.cpp \ $(internal_src_dir)/render/renderers/render-renderer.cpp \ diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index e9e13e81b..a69d02f8c 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include #include @@ -58,6 +60,8 @@ struct RenderManager::Impl Integration::DepthBufferAvailable depthBufferAvailableParam, Integration::StencilBufferAvailable stencilBufferAvailableParam ) : context( glAbstraction ), + currentContext( &context ), + glAbstraction( glAbstraction ), glSyncAbstraction( glSyncAbstraction ), renderQueue(), instructions(), @@ -92,6 +96,17 @@ struct RenderManager::Impl mRenderTrackers.EraseObject( renderTracker ); } + Context* CreateSurfaceContext() + { + surfaceContextContainer.PushBack( new Context( glAbstraction ) ); + return surfaceContextContainer[ surfaceContextContainer.Count() - 1 ]; + } + + void DestroySurfaceContext( Context* surfaceContext ) + { + surfaceContextContainer.EraseObject( surfaceContext ); + } + void UpdateTrackers() { for( auto&& iter : mRenderTrackers ) @@ -102,7 +117,10 @@ struct RenderManager::Impl // the order is important for destruction, // programs are owned by context at the moment. - Context context; ///< holds the GL state + Context context; ///< Holds the GL state of the share resource context + Context* currentContext; ///< Holds the GL state of the current context for rendering + OwnerContainer< Context* > surfaceContextContainer; ///< List of owned contexts holding the GL state per surface + Integration::GlAbstraction& glAbstraction; ///< GL abstraction Integration::GlSyncAbstraction& glSyncAbstraction; ///< GL sync abstraction RenderQueue renderQueue; ///< A message queue for receiving messages from the update-thread. @@ -288,7 +306,14 @@ void RenderManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, u void RenderManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer ) { mImpl->frameBufferContainer.PushBack( frameBuffer ); - frameBuffer->Initialize(mImpl->context); + if ( frameBuffer->IsSurfaceBacked() ) + { + frameBuffer->Initialize( *mImpl->CreateSurfaceContext() ); + } + else + { + frameBuffer->Initialize( mImpl->context ); + } } void RenderManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer ) @@ -301,7 +326,15 @@ void RenderManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer ) if ( iter == frameBuffer ) { frameBuffer->Destroy( mImpl->context ); + + if ( frameBuffer->IsSurfaceBacked() ) + { + auto surfaceFrameBuffer = static_cast( frameBuffer ); + mImpl->DestroySurfaceContext( surfaceFrameBuffer->GetContext() ); + } + mImpl->frameBufferContainer.Erase( &iter ); // frameBuffer found; now destroy it + break; } } @@ -309,7 +342,11 @@ void RenderManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer ) void RenderManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer ) { - frameBuffer->AttachColorTexture( mImpl->context, texture, mipmapLevel, layer ); + if ( !frameBuffer->IsSurfaceBacked() ) + { + auto textureFrameBuffer = static_cast( frameBuffer ); + textureFrameBuffer->AttachColorTexture( mImpl->context, texture, mipmapLevel, layer ); + } } void RenderManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer ) @@ -419,48 +456,50 @@ void RenderManager::Render( Integration::RenderStatus& status, bool forceClear ) // Mark that we will require a post-render step to be performed (includes swap-buffers). status.SetNeedsPostRender( true ); - // switch rendering to adaptor provided (default) buffer - mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, 0u ); - - mImpl->context.Viewport( mImpl->defaultSurfaceRect.x, - mImpl->defaultSurfaceRect.y, - mImpl->defaultSurfaceRect.width, - mImpl->defaultSurfaceRect.height ); - - mImpl->context.ClearColor( mImpl->backgroundColor.r, - mImpl->backgroundColor.g, - mImpl->backgroundColor.b, - mImpl->backgroundColor.a ); - - // Clear the entire color, depth and stencil buffers for the default framebuffer, if required. - // It is important to clear all 3 buffers when they are being used, for performance on deferred renderers - // e.g. previously when the depth & stencil buffers were NOT cleared, it caused the DDK to exceed a "vertex count limit", - // and then stall. That problem is only noticeable when rendering a large number of vertices per frame. - - mImpl->context.SetScissorTest( false ); - - GLbitfield clearMask = GL_COLOR_BUFFER_BIT; - - mImpl->context.ColorMask( true ); - - if( mImpl->depthBufferAvailable == Integration::DepthBufferAvailable::TRUE ) + // Switch to the shared context + if ( mImpl->currentContext != &mImpl->context ) { - mImpl->context.DepthMask( true ); - clearMask |= GL_DEPTH_BUFFER_BIT; + mImpl->currentContext = &mImpl->context; + // Clear the current cached program when the context is switched + mImpl->programController.ClearCurrentProgram(); } - if( mImpl->stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE) - { - mImpl->context.ClearStencil( 0 ); - mImpl->context.StencilMask( 0xFF ); // 8 bit stencil mask, all 1's - clearMask |= GL_STENCIL_BUFFER_BIT; - } - mImpl->context.Clear( clearMask, Context::FORCE_CLEAR ); + // Upload the geometries + for( uint32_t i = 0; i < count; ++i ) + { + RenderInstruction& instruction = mImpl->instructions.At( mImpl->renderBufferIndex, i ); - // reset the program matrices for all programs once per frame - // this ensures we will set view and projection matrix once per program per camera - mImpl->programController.ResetProgramMatrices(); + const Matrix* viewMatrix = instruction.GetViewMatrix( mImpl->renderBufferIndex ); + const Matrix* projectionMatrix = instruction.GetProjectionMatrix( mImpl->renderBufferIndex ); + + DALI_ASSERT_DEBUG( viewMatrix ); + DALI_ASSERT_DEBUG( projectionMatrix ); + + if( viewMatrix && projectionMatrix ) + { + const RenderListContainer::SizeType renderListCount = instruction.RenderListCount(); + + // Iterate through each render list. + for( RenderListContainer::SizeType index = 0; index < renderListCount; ++index ) + { + const RenderList* renderList = instruction.GetRenderList( index ); + + if( renderList && !renderList->IsEmpty() ) + { + const std::size_t itemCount = renderList->Count(); + for( uint32_t itemIndex = 0u; itemIndex < itemCount; ++itemIndex ) + { + const RenderItem& item = renderList->GetItem( itemIndex ); + if( DALI_LIKELY( item.mRenderer ) ) + { + item.mRenderer->Upload( *mImpl->currentContext ); + } + } + } + } + } + } for( uint32_t i = 0; i < count; ++i ) { @@ -471,6 +510,10 @@ void RenderManager::Render( Integration::RenderStatus& status, bool forceClear ) GLenum attachments[] = { GL_DEPTH, GL_STENCIL }; mImpl->context.InvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments); + for ( auto&& context : mImpl->surfaceContextContainer ) + { + context->InvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments); + } //Notify RenderGeometries that rendering has finished for ( auto&& iter : mImpl->geometryContainer ) @@ -508,63 +551,155 @@ void RenderManager::DoRender( RenderInstruction& instruction ) clearColor = Dali::RenderTask::DEFAULT_CLEAR_COLOR; } + Rect surfaceRect = mImpl->defaultSurfaceRect; + Vector4 backgroundColor = mImpl->backgroundColor; + Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable; + Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable; + + Render::SurfaceFrameBuffer* surfaceFrameBuffer = nullptr; + if ( ( instruction.mFrameBuffer != 0 ) && instruction.mFrameBuffer->IsSurfaceBacked() ) + { + surfaceFrameBuffer = static_cast( instruction.mFrameBuffer ); + +#if DALI_GLES_VERSION >= 30 + Context* surfaceContext = surfaceFrameBuffer->GetContext(); + if ( mImpl->currentContext != surfaceContext ) + { + // Switch the correct context if rendering to a surface + mImpl->currentContext = surfaceContext; + // Clear the current cached program when the context is switched + mImpl->programController.ClearCurrentProgram(); + } +#endif + + surfaceRect = Rect( 0, 0, static_cast( surfaceFrameBuffer->GetWidth() ), static_cast( surfaceFrameBuffer->GetHeight() ) ); + backgroundColor = surfaceFrameBuffer->GetBackgroundColor(); + } + + DALI_ASSERT_DEBUG( mImpl->currentContext->IsGlContextCreated() ); + + // reset the program matrices for all programs once per frame + // this ensures we will set view and projection matrix once per program per camera + mImpl->programController.ResetProgramMatrices(); + + if( instruction.mFrameBuffer ) + { + instruction.mFrameBuffer->Bind( *mImpl->currentContext ); + } + + mImpl->currentContext->Viewport( surfaceRect.x, + surfaceRect.y, + surfaceRect.width, + surfaceRect.height ); + + mImpl->currentContext->ClearColor( backgroundColor.r, + backgroundColor.g, + backgroundColor.b, + backgroundColor.a ); + + // Clear the entire color, depth and stencil buffers for the default framebuffer, if required. + // It is important to clear all 3 buffers when they are being used, for performance on deferred renderers + // e.g. previously when the depth & stencil buffers were NOT cleared, it caused the DDK to exceed a "vertex count limit", + // and then stall. That problem is only noticeable when rendering a large number of vertices per frame. + + mImpl->currentContext->SetScissorTest( false ); + + GLbitfield clearMask = GL_COLOR_BUFFER_BIT; + + mImpl->currentContext->ColorMask( true ); + + if( depthBufferAvailable == Integration::DepthBufferAvailable::TRUE ) + { + mImpl->currentContext->DepthMask( true ); + clearMask |= GL_DEPTH_BUFFER_BIT; + } + + if( stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE) + { + mImpl->currentContext->ClearStencil( 0 ); + mImpl->currentContext->StencilMask( 0xFF ); // 8 bit stencil mask, all 1's + clearMask |= GL_STENCIL_BUFFER_BIT; + } + + mImpl->currentContext->Clear( clearMask, Context::FORCE_CLEAR ); + if( !instruction.mIgnoreRenderToFbo && ( instruction.mFrameBuffer != 0 ) ) { - instruction.mFrameBuffer->Bind( mImpl->context ); - if ( instruction.mIsViewportSet ) + if ( instruction.mFrameBuffer->IsSurfaceBacked() ) // Surface rendering { - // For glViewport the lower-left corner is (0,0) - const int32_t y = ( instruction.mFrameBuffer->GetHeight() - instruction.mViewport.height ) - instruction.mViewport.y; - viewportRect.Set( instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height ); + if ( instruction.mIsViewportSet ) + { + // For glViewport the lower-left corner is (0,0) + // For glViewport the lower-left corner is (0,0) + const int32_t y = ( surfaceRect.height - instruction.mViewport.height ) - instruction.mViewport.y; + viewportRect.Set( instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height ); + } + else + { + viewportRect = surfaceRect; + } } - else + else // Offscreen buffer rendering { - viewportRect.Set( 0, 0, instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight() ); + if ( instruction.mIsViewportSet ) + { + // For glViewport the lower-left corner is (0,0) + const int32_t y = ( instruction.mFrameBuffer->GetHeight() - instruction.mViewport.height ) - instruction.mViewport.y; + viewportRect.Set( instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height ); + } + else + { + viewportRect.Set( 0, 0, instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight() ); + } } } - else // !(instruction.mOffscreenTexture) + else // No Offscreen frame buffer rendering { - // switch rendering to adaptor provided (default) buffer - mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, 0 ); - // Check whether a viewport is specified, otherwise the full surface size is used - if ( instruction.mIsViewportSet ) + if ( instruction.mFrameBuffer != 0 ) { - // For glViewport the lower-left corner is (0,0) - const int32_t y = ( mImpl->defaultSurfaceRect.height - instruction.mViewport.height ) - instruction.mViewport.y; - viewportRect.Set( instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height ); + if ( instruction.mIsViewportSet ) + { + // For glViewport the lower-left corner is (0,0) + const int32_t y = ( instruction.mFrameBuffer->GetHeight() - instruction.mViewport.height ) - instruction.mViewport.y; + viewportRect.Set( instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height ); + } + else + { + viewportRect.Set( 0, 0, instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight() ); + } } else { - viewportRect = mImpl->defaultSurfaceRect; + viewportRect = surfaceRect; } } - mImpl->context.Viewport(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height); + mImpl->currentContext->Viewport(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height); if ( instruction.mIsClearColorSet ) { - mImpl->context.ClearColor( clearColor.r, - clearColor.g, - clearColor.b, - clearColor.a ); + mImpl->currentContext->ClearColor( clearColor.r, + clearColor.g, + clearColor.b, + clearColor.a ); // Clear the viewport area only - mImpl->context.SetScissorTest( true ); - mImpl->context.Scissor( viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height ); - mImpl->context.ColorMask( true ); - mImpl->context.Clear( GL_COLOR_BUFFER_BIT , Context::CHECK_CACHED_VALUES ); - mImpl->context.SetScissorTest( false ); + mImpl->currentContext->SetScissorTest( true ); + mImpl->currentContext->Scissor( viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height ); + mImpl->currentContext->ColorMask( true ); + mImpl->currentContext->Clear( GL_COLOR_BUFFER_BIT , Context::CHECK_CACHED_VALUES ); + mImpl->currentContext->SetScissorTest( false ); } mImpl->renderAlgorithms.ProcessRenderInstruction( instruction, - mImpl->context, + *mImpl->currentContext, mImpl->renderBufferIndex, - mImpl->depthBufferAvailable, - mImpl->stencilBufferAvailable ); + depthBufferAvailable, + stencilBufferAvailable ); - if( instruction.mRenderTracker && ( instruction.mFrameBuffer != NULL ) ) + if( instruction.mRenderTracker && ( instruction.mFrameBuffer != 0 ) ) { // This will create a sync object every frame this render tracker // is alive (though it should be now be created only for @@ -572,6 +707,11 @@ void RenderManager::DoRender( RenderInstruction& instruction ) instruction.mRenderTracker->CreateSyncObject( mImpl->glSyncAbstraction ); instruction.mRenderTracker = NULL; // Only create once. } + + if ( surfaceFrameBuffer ) + { + surfaceFrameBuffer->PostRender(); + } } } // namespace SceneGraph diff --git a/dali/internal/render/gl-resources/gpu-buffer.cpp b/dali/internal/render/gl-resources/gpu-buffer.cpp index 257b12ad5..9b8799fdc 100644 --- a/dali/internal/render/gl-resources/gpu-buffer.cpp +++ b/dali/internal/render/gl-resources/gpu-buffer.cpp @@ -85,7 +85,7 @@ GpuBuffer::~GpuBuffer() * Creates or updates the buffer data depending on whether it * already exists or not. */ -void GpuBuffer::UpdateDataBuffer(GLsizeiptr size, const GLvoid *data, Usage usage, Target target) +void GpuBuffer::UpdateDataBuffer(Context& context, GLsizeiptr size, const GLvoid *data, Usage usage, Target target) { DALI_ASSERT_DEBUG( size > 0 ); mSize = size; @@ -101,17 +101,17 @@ void GpuBuffer::UpdateDataBuffer(GLsizeiptr size, const GLvoid *data, Usage usag // make sure the buffer is bound, don't perform any checks because size may be zero if(ARRAY_BUFFER == target) { - mContext.BindArrayBuffer( mBufferId ); + context.BindArrayBuffer( mBufferId ); } else if(ELEMENT_ARRAY_BUFFER == target) { glTargetEnum = GL_ELEMENT_ARRAY_BUFFER; - mContext.BindElementArrayBuffer( mBufferId ); + context.BindElementArrayBuffer( mBufferId ); } else if(TRANSFORM_FEEDBACK_BUFFER == target) { glTargetEnum = GL_TRANSFORM_FEEDBACK_BUFFER; - mContext.BindTransformFeedbackBuffer( mBufferId ); + context.BindTransformFeedbackBuffer( mBufferId ); } // if the buffer has already been created, just update the data providing it fits @@ -120,53 +120,53 @@ void GpuBuffer::UpdateDataBuffer(GLsizeiptr size, const GLvoid *data, Usage usag // if the data will fit in the existing buffer, just update it if (size <= mCapacity ) { - mContext.BufferSubData( glTargetEnum, 0, size, data ); + context.BufferSubData( glTargetEnum, 0, size, data ); } else { // create a new buffer of the larger size, // gl should automatically deallocate the old buffer - mContext.BufferData( glTargetEnum, size, data, ModeAsGlEnum( usage ) ); + context.BufferData( glTargetEnum, size, data, ModeAsGlEnum( usage ) ); mCapacity = size; } } else { // create the buffer - mContext.BufferData( glTargetEnum, size, data, ModeAsGlEnum( usage ) ); + context.BufferData( glTargetEnum, size, data, ModeAsGlEnum( usage ) ); mBufferCreated = true; mCapacity = size; } if(ARRAY_BUFFER == target) { - mContext.BindArrayBuffer( 0 ); + context.BindArrayBuffer( 0 ); } else if(ELEMENT_ARRAY_BUFFER == target) { - mContext.BindElementArrayBuffer( 0 ); + context.BindElementArrayBuffer( 0 ); } else if(TRANSFORM_FEEDBACK_BUFFER == target) { - mContext.BindTransformFeedbackBuffer( 0 ); + context.BindTransformFeedbackBuffer( 0 ); } } -void GpuBuffer::Bind(Target target) const +void GpuBuffer::Bind(Context& context, Target target) const { DALI_ASSERT_DEBUG(mCapacity); if (target == ARRAY_BUFFER) { - mContext.BindArrayBuffer(mBufferId); + context.BindArrayBuffer(mBufferId); } else if (target == ELEMENT_ARRAY_BUFFER) { - mContext.BindElementArrayBuffer(mBufferId); + context.BindElementArrayBuffer(mBufferId); } else if (target == TRANSFORM_FEEDBACK_BUFFER) { - mContext.BindTransformFeedbackBuffer(mBufferId); + context.BindTransformFeedbackBuffer(mBufferId); } } diff --git a/dali/internal/render/gl-resources/gpu-buffer.h b/dali/internal/render/gl-resources/gpu-buffer.h index 7c32719a1..662a18094 100644 --- a/dali/internal/render/gl-resources/gpu-buffer.h +++ b/dali/internal/render/gl-resources/gpu-buffer.h @@ -77,18 +77,21 @@ public: /** * * Creates or updates a buffer object and binds it to the target. + * @param context The context to bind the the buffer * @param size Specifies the size in bytes of the buffer object's new data store. * @param data pointer to the data to load * @param usage How the buffer will be used * @param target The target buffer to update */ - void UpdateDataBuffer(GLsizeiptr size, const GLvoid *data, Usage usage, Target target); + void UpdateDataBuffer(Context& context, GLsizeiptr size, const GLvoid *data, Usage usage, Target target); /** * Bind the buffer object to the target * Will assert if the buffer size is zero + * @param context The context to bind the the buffer + * @param target The target buffer to bind */ - void Bind(Target target) const; + void Bind(Context& context, Target target) const; /** * @return true if the GPU buffer is valid, i.e. its created and not empty @@ -119,7 +122,7 @@ private: private: // Data - Context& mContext; ///< dali drawing context + Context& mContext; ///< shared context for dali drawing GLsizeiptr mCapacity; ///< buffer capacity GLsizeiptr mSize; ///< buffer size GLuint mBufferId; ///< buffer object name(id) diff --git a/dali/internal/render/renderers/render-frame-buffer.cpp b/dali/internal/render/renderers/render-frame-buffer.cpp deleted file mode 100644 index 2ea746e41..000000000 --- a/dali/internal/render/renderers/render-frame-buffer.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2018 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 -{ -namespace Internal -{ -namespace Render -{ - -FrameBuffer::FrameBuffer( uint32_t width, uint32_t height, Mask attachments ) -:mId( 0u ), - mDepthBuffer( attachments & Dali::FrameBuffer::Attachment::DEPTH ), - mStencilBuffer( attachments & Dali::FrameBuffer::Attachment::STENCIL ), - mWidth( width ), - mHeight( height ) -{ -} - -FrameBuffer::~FrameBuffer() -{} - -void FrameBuffer::Destroy( Context& context ) -{ - if( mId ) - { - context.DeleteFramebuffers( 1, &mId ); - } -} - -void FrameBuffer::GlContextDestroyed() -{ - mId = 0u; -} - -void FrameBuffer::Initialize(Context& context) -{ - context.GenFramebuffers( 1, &mId ); - context.BindFramebuffer( GL_FRAMEBUFFER, mId ); - - if( mDepthBuffer ) - { - // Create a depth render target. - context.GenRenderbuffers( 1, &mDepthBuffer ); - context.BindRenderbuffer( GL_RENDERBUFFER, mDepthBuffer ); - context.RenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mWidth, mHeight ); - context.FramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer ); - } - - if( mStencilBuffer ) - { - // Create a stencil render target. - context.GenRenderbuffers( 1, &mStencilBuffer ); - context.BindRenderbuffer( GL_RENDERBUFFER, mStencilBuffer ); - context.RenderbufferStorage( GL_RENDERBUFFER, GL_STENCIL_INDEX8, mWidth, mHeight ); - context.FramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBuffer ); - } - - context.BindFramebuffer( GL_FRAMEBUFFER, 0 ); -} - -void FrameBuffer::AttachColorTexture( Context& context, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer ) -{ - context.BindFramebuffer( GL_FRAMEBUFFER, mId ); - - // Create a color attachment. - if( texture->GetType() == TextureType::TEXTURE_2D ) - { - if( !texture->IsNativeImage() ) - { - context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->GetId(), mipmapLevel ); - } - else - { - // If it's a native image we need to use GL_TEXTURE_EXTERNAL_OES as the texture target parameter - context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, texture->GetId(), mipmapLevel ); - } - } - else - { - context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, texture->GetId(), mipmapLevel ); - } - - context.BindFramebuffer( GL_FRAMEBUFFER, 0 ); -} - -void FrameBuffer::Bind( Context& context ) -{ - context.BindFramebuffer( GL_FRAMEBUFFER, mId ); -} - -uint32_t FrameBuffer::GetWidth() const -{ - return mWidth; -} - -uint32_t FrameBuffer::GetHeight() const -{ - return mHeight; -} - - -} //Render - -} //Internal - -} //Dali diff --git a/dali/internal/render/renderers/render-frame-buffer.h b/dali/internal/render/renderers/render-frame-buffer.h index 196630dfc..16d2a73c8 100644 --- a/dali/internal/render/renderers/render-frame-buffer.h +++ b/dali/internal/render/renderers/render-frame-buffer.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_RENDER_FRAME_BUFFER_H /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -29,80 +29,75 @@ namespace Internal { namespace Render { -class Texture; class FrameBuffer { public: - using Mask = Dali::FrameBuffer::Attachment::Mask; - /** * Constructor - * @param[in] width The width of the FrameBuffer - * @param[in] height The height of the FrameBuffer - * @param[in] attachments The attachments comprising the format of the FrameBuffer (bit-mask) */ - FrameBuffer( uint32_t width, uint32_t height, Mask attachments ); + FrameBuffer() {}; /** * Destructor */ - ~FrameBuffer(); + virtual ~FrameBuffer() {}; /** * Creates a FrameBuffer object in the GPU. * @param[in] context The GL context */ - void Initialize(Context& context); + virtual void Initialize( Context& context ) = 0; /** * Deletes the framebuffer object from the GPU * @param[in] context The GL context */ - void Destroy( Context& context ); + virtual void Destroy( Context& context ) = 0; /** * Called by RenderManager to inform the framebuffer that the context has been destroyed */ - void GlContextDestroyed(); - - /** - * @brief Attach a texture for color rendering. Valid only for Framebuffers with COLOR attachments. - * param[in] context The GL context - * @param[in] texture The texture that will be used as output when rendering - * @param[in] mipmapLevel The mipmap of the texture to be attached - * @param[in] layer Indicates which layer of a cube map or array texture to attach. Unused for 2D textures - */ - void AttachColorTexture( Context& context, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer ); + virtual void GlContextDestroyed() = 0; /** * @brief Bind the framebuffer * @param[in] context The GL context */ - void Bind( Context& context ); + virtual void Bind( Context& context ) = 0; /** * @brief Get the width of the FrameBuffer * @return The width of the framebuffer */ - uint32_t GetWidth() const; + virtual uint32_t GetWidth() const = 0; /** * @brief Get the height of the FrameBuffer * @return The height of the framebuffer */ - uint32_t GetHeight() const; + virtual uint32_t GetHeight() const = 0; + + /** + * @brief Check whether the FrameBuffer is backed by a render surface + * @return True if the FrameBuffer is backed by a render surface + */ + virtual bool IsSurfaceBacked() = 0; private: - GLuint mId; - GLuint mDepthBuffer; - GLuint mStencilBuffer; - uint32_t mWidth; - uint32_t mHeight; -}; + /** + * @brief Undefined copy constructor. FrameBuffer cannot be copied + */ + FrameBuffer( const FrameBuffer& rhs ) = delete; + /** + * @brief Undefined assignment operator. FrameBuffer cannot be copied + */ + FrameBuffer& operator=( const FrameBuffer& rhs ) = delete; + +}; } // namespace Render diff --git a/dali/internal/render/renderers/render-geometry.cpp b/dali/internal/render/renderers/render-geometry.cpp index afc96ba33..17ba52269 100644 --- a/dali/internal/render/renderers/render-geometry.cpp +++ b/dali/internal/render/renderers/render-geometry.cpp @@ -109,12 +109,7 @@ void Geometry::OnRenderFinished() mAttributesChanged = false; } -void Geometry::UploadAndDraw( - Context& context, - BufferIndex bufferIndex, - Vector& attributeLocation, - uint32_t elementBufferOffset, - uint32_t elementBufferCount ) +void Geometry::Upload( Context& context ) { if( !mHasBeenUpdated ) { @@ -133,7 +128,7 @@ void Geometry::UploadAndDraw( } uint32_t bufferSize = static_cast( sizeof( uint16_t ) * mIndices.Size() ); - mIndexBuffer->UpdateDataBuffer( bufferSize, &mIndices[0], GpuBuffer::STATIC_DRAW, GpuBuffer::ELEMENT_ARRAY_BUFFER ); + mIndexBuffer->UpdateDataBuffer( context, bufferSize, &mIndices[0], GpuBuffer::STATIC_DRAW, GpuBuffer::ELEMENT_ARRAY_BUFFER ); } mIndicesChanged = false; @@ -150,13 +145,21 @@ void Geometry::UploadAndDraw( mHasBeenUpdated = true; } +} +void Geometry::Draw( + Context& context, + BufferIndex bufferIndex, + Vector& attributeLocation, + uint32_t elementBufferOffset, + uint32_t elementBufferCount ) +{ //Bind buffers to attribute locations uint32_t base = 0u; const uint32_t vertexBufferCount = static_cast( mVertexBuffers.Count() ); for( uint32_t i = 0; i < vertexBufferCount; ++i ) { - mVertexBuffers[i]->BindBuffer( GpuBuffer::ARRAY_BUFFER ); + mVertexBuffers[i]->BindBuffer( context, GpuBuffer::ARRAY_BUFFER ); base += mVertexBuffers[i]->EnableVertexAttributes( context, attributeLocation, base ); } @@ -223,7 +226,7 @@ void Geometry::UploadAndDraw( if( mIndexBuffer && geometryGLType != GL_POINTS ) { //Indexed draw call - mIndexBuffer->Bind( GpuBuffer::ELEMENT_ARRAY_BUFFER ); + mIndexBuffer->Bind( context, GpuBuffer::ELEMENT_ARRAY_BUFFER ); // numIndices truncated, no value loss happening in practice context.DrawElements( geometryGLType, static_cast( numIndices ), GL_UNSIGNED_SHORT, reinterpret_cast( firstIndexOffset ) ); } diff --git a/dali/internal/render/renderers/render-geometry.h b/dali/internal/render/renderers/render-geometry.h index 4e12e1c7d..f08cbce71 100644 --- a/dali/internal/render/renderers/render-geometry.h +++ b/dali/internal/render/renderers/render-geometry.h @@ -116,19 +116,24 @@ public: } /** - * Upload the geometry if it has changed, set up the attributes and perform - * the Draw call corresponding to the geometry type + * Upload the geometry if it has changed + * @param[in] context The GL context + */ + void Upload( Context& context ); + + /** + * Set up the attributes and perform the Draw call corresponding to the geometry type * @param[in] context The GL context * @param[in] bufferIndex The current buffer index * @param[in] attributeLocation The location for the attributes in the shader * @param[in] elementBufferOffset The index of first element to draw if index buffer bound * @param[in] elementBufferCount Number of elements to draw if index buffer bound, uses whole buffer when 0 */ - void UploadAndDraw(Context& context, - BufferIndex bufferIndex, - Vector& attributeLocation, - uint32_t elementBufferOffset, - uint32_t elementBufferCount ); + void Draw(Context& context, + BufferIndex bufferIndex, + Vector& attributeLocation, + uint32_t elementBufferOffset, + uint32_t elementBufferCount ); private: diff --git a/dali/internal/render/renderers/render-property-buffer.cpp b/dali/internal/render/renderers/render-property-buffer.cpp index 5197837f8..597602053 100644 --- a/dali/internal/render/renderers/render-property-buffer.cpp +++ b/dali/internal/render/renderers/render-property-buffer.cpp @@ -160,7 +160,7 @@ bool PropertyBuffer::Update( Context& context ) if ( mGpuBuffer ) { DALI_ASSERT_DEBUG( mSize && "No data in the property buffer!" ); - mGpuBuffer->UpdateDataBuffer( GetDataSize(), &((*mData)[0]), GpuBuffer::STATIC_DRAW, GpuBuffer::ARRAY_BUFFER ); + mGpuBuffer->UpdateDataBuffer( context, GetDataSize(), &((*mData)[0]), GpuBuffer::STATIC_DRAW, GpuBuffer::ARRAY_BUFFER ); } mDataChanged = false; @@ -169,11 +169,11 @@ bool PropertyBuffer::Update( Context& context ) return true; } -void PropertyBuffer::BindBuffer(GpuBuffer::Target target) +void PropertyBuffer::BindBuffer( Context& context, GpuBuffer::Target target ) { if(mGpuBuffer) { - mGpuBuffer->Bind(target); + mGpuBuffer->Bind(context, target); } } diff --git a/dali/internal/render/renderers/render-property-buffer.h b/dali/internal/render/renderers/render-property-buffer.h index 436bd068b..13771f532 100644 --- a/dali/internal/render/renderers/render-property-buffer.h +++ b/dali/internal/render/renderers/render-property-buffer.h @@ -89,9 +89,10 @@ public: /** * @brief Bind the property buffer + * @param context The context to bind the the buffer * @param[in] target The binding point */ - void BindBuffer(GpuBuffer::Target target); + void BindBuffer( Context& context, GpuBuffer::Target target ); /** * Perform the upload of the buffer only when requiered diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 4beee2ed9..2222abd8e 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -506,6 +506,11 @@ StencilOperation::Type Renderer::GetStencilOperationOnZPass() const return mStencilParameters.stencilOperationOnZPass; } +void Renderer::Upload( Context& context ) +{ + mGeometry->Upload( context ); +} + void Renderer::Render( Context& context, BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, @@ -564,11 +569,11 @@ void Renderer::Render( Context& context, mUpdateAttributesLocation = false; } - mGeometry->UploadAndDraw( context, - bufferIndex, - mAttributesLocation, - mIndexedDrawFirstElement, - mIndexedDrawElementsCount ); + mGeometry->Draw( context, + bufferIndex, + mAttributesLocation, + mIndexedDrawFirstElement, + mIndexedDrawElementsCount ); } } diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index 1f8d99e10..66e33aaf4 100755 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_RENDER_RENDERER_H /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -334,6 +334,12 @@ public: */ StencilOperation::Type GetStencilOperationOnZPass() const; + /** + * Called to upload during RenderManager::Render(). + * @param[in] context The context used for uploading + */ + void Upload( Context& context ); + /** * Called to render during RenderManager::Render(). * @param[in] context The context used for rendering diff --git a/dali/internal/render/renderers/render-surface-frame-buffer.cpp b/dali/internal/render/renderers/render-surface-frame-buffer.cpp new file mode 100644 index 000000000..7cc38bb2d --- /dev/null +++ b/dali/internal/render/renderers/render-surface-frame-buffer.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019 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 +{ +namespace Internal +{ +namespace Render +{ + +SurfaceFrameBuffer::SurfaceFrameBuffer( Integration::RenderSurface* surface ) +: FrameBuffer(), + mSurface( surface ), + mContext( nullptr ) +{ +} + +SurfaceFrameBuffer::~SurfaceFrameBuffer() +{} + +void SurfaceFrameBuffer::Destroy( Context& context ) +{ +} + +void SurfaceFrameBuffer::GlContextDestroyed() +{ + if ( mContext ) + { + mContext->GlContextDestroyed(); + } +} + +void SurfaceFrameBuffer::Initialize(Context& context) +{ + mContext = &context; + mContext->GlContextCreated(); + mSurface->InitializeGraphics(); +} + +void SurfaceFrameBuffer::Bind( Context& context ) +{ + mSurface->PreRender( false ); + context.BindFramebuffer( GL_FRAMEBUFFER, 0u ); +} + +uint32_t SurfaceFrameBuffer::GetWidth() const +{ + return mSurface->GetPositionSize().width; +} + +uint32_t SurfaceFrameBuffer::GetHeight() const +{ + return mSurface->GetPositionSize().height; +} + +void SurfaceFrameBuffer::PostRender() +{ + mSurface->PostRender( false, false, false ); +} + +Context* SurfaceFrameBuffer::GetContext() +{ + return mContext; +} + +Integration::DepthBufferAvailable SurfaceFrameBuffer::GetDepthBufferRequired() +{ + return mSurface->GetDepthBufferRequired(); +} + +Integration::StencilBufferAvailable SurfaceFrameBuffer::GetStencilBufferRequired() +{ + return mSurface->GetStencilBufferRequired(); +} + +Vector4 SurfaceFrameBuffer::GetBackgroundColor() +{ + return mSurface->GetBackgroundColor(); +} + +} //Render + +} //Internal + +} //Dali diff --git a/dali/internal/render/renderers/render-surface-frame-buffer.h b/dali/internal/render/renderers/render-surface-frame-buffer.h new file mode 100644 index 000000000..576ea65e5 --- /dev/null +++ b/dali/internal/render/renderers/render-surface-frame-buffer.h @@ -0,0 +1,130 @@ +#ifndef DALI_INTERNAL_RENDER_SURFACE_FRAME_BUFFER_H +#define DALI_INTERNAL_RENDER_SURFACE_FRAME_BUFFER_H + +/* + * Copyright (c) 2019 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 +{ + +namespace Internal +{ + +class Context; + +namespace Render +{ + +class SurfaceFrameBuffer : public FrameBuffer +{ +public: + + /** + * Constructor + * @param[in] surface The render surface + */ + SurfaceFrameBuffer( Integration::RenderSurface* surface ); + + /** + * Destructor + */ + virtual ~SurfaceFrameBuffer(); + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::Initialize() + */ + void Initialize( Context& context ) override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::Destroy() + */ + void Destroy( Context& context ) override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::GlContextDestroyed() + */ + void GlContextDestroyed() override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::Bind() + */ + void Bind( Context& context ) override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::GetWidth() + */ + uint32_t GetWidth() const override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::GetHeight() + */ + uint32_t GetHeight() const override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::IsSurfaceBacked() + */ + bool IsSurfaceBacked() override { return true; }; + +public: + + /** + * Called after this frame buffer is rendered in the render manager + */ + void PostRender(); + + /** + * Gets the context holding the GL state of rendering for the surface + * @return the context + */ + Context* GetContext(); + + /** + * @brief Gets whether the depth buffer is required + * @return TRUE if the depth buffer is required + */ + Integration::DepthBufferAvailable GetDepthBufferRequired(); + + /** + * @brief Gets whether the stencil buffer is required + * @return TRUE if the stencil buffer is required + */ + Integration::StencilBufferAvailable GetStencilBufferRequired(); + + /** + * @brief Gets the background color of the surface. + * @return The background color + */ + Vector4 GetBackgroundColor(); + +private: + + Integration::RenderSurface* mSurface; ///< The render surface + Context* mContext; ///< The context holding the GL state of rendering for the surface backed frame buffer +}; + + +} // namespace Render + +} // namespace Internal + +} // namespace Dali + + +#endif // DALI_INTERNAL_RENDER_SURFACE_FRAME_BUFFER_H diff --git a/dali/internal/render/renderers/render-texture-frame-buffer.cpp b/dali/internal/render/renderers/render-texture-frame-buffer.cpp new file mode 100644 index 000000000..9e3120e34 --- /dev/null +++ b/dali/internal/render/renderers/render-texture-frame-buffer.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2019 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 +{ +namespace Internal +{ +namespace Render +{ + +TextureFrameBuffer::TextureFrameBuffer( uint32_t width, uint32_t height, Mask attachments ) +: FrameBuffer(), + mId( 0u ), + mDepthBuffer( attachments & Dali::FrameBuffer::Attachment::DEPTH ), + mStencilBuffer( attachments & Dali::FrameBuffer::Attachment::STENCIL ), + mWidth( width ), + mHeight( height ) +{ +} + +TextureFrameBuffer::~TextureFrameBuffer() +{} + +void TextureFrameBuffer::Destroy( Context& context ) +{ + if( mId ) + { + context.DeleteFramebuffers( 1, &mId ); + } +} + +void TextureFrameBuffer::GlContextDestroyed() +{ + mId = 0u; +} + +void TextureFrameBuffer::Initialize(Context& context) +{ + context.GenFramebuffers( 1, &mId ); + context.BindFramebuffer( GL_FRAMEBUFFER, mId ); + + if( mDepthBuffer ) + { + // Create a depth render target. + context.GenRenderbuffers( 1, &mDepthBuffer ); + context.BindRenderbuffer( GL_RENDERBUFFER, mDepthBuffer ); + context.RenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mWidth, mHeight ); + context.FramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer ); + } + + if( mStencilBuffer ) + { + // Create a stencil render target. + context.GenRenderbuffers( 1, &mStencilBuffer ); + context.BindRenderbuffer( GL_RENDERBUFFER, mStencilBuffer ); + context.RenderbufferStorage( GL_RENDERBUFFER, GL_STENCIL_INDEX8, mWidth, mHeight ); + context.FramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBuffer ); + } + + context.BindFramebuffer( GL_FRAMEBUFFER, 0 ); +} + +void TextureFrameBuffer::AttachColorTexture( Context& context, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer ) +{ + context.BindFramebuffer( GL_FRAMEBUFFER, mId ); + + // Create a color attachment. + if( texture->GetType() == TextureType::TEXTURE_2D ) + { + if( !texture->IsNativeImage() ) + { + context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->GetId(), mipmapLevel ); + } + else + { + // If it's a native image we need to use GL_TEXTURE_EXTERNAL_OES as the texture target parameter + context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, texture->GetId(), mipmapLevel ); + } + } + else + { + context.FramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, texture->GetId(), mipmapLevel ); + } + + context.BindFramebuffer( GL_FRAMEBUFFER, 0 ); +} + +void TextureFrameBuffer::Bind( Context& context ) +{ + context.BindFramebuffer( GL_FRAMEBUFFER, mId ); +} + +uint32_t TextureFrameBuffer::GetWidth() const +{ + return mWidth; +} + +uint32_t TextureFrameBuffer::GetHeight() const +{ + return mHeight; +} + + +} //Render + +} //Internal + +} //Dali diff --git a/dali/internal/render/renderers/render-texture-frame-buffer.h b/dali/internal/render/renderers/render-texture-frame-buffer.h new file mode 100644 index 000000000..021890f82 --- /dev/null +++ b/dali/internal/render/renderers/render-texture-frame-buffer.h @@ -0,0 +1,111 @@ +#ifndef DALI_INTERNAL_RENDER_TEXTURE_FRAME_BUFFER_H +#define DALI_INTERNAL_RENDER_TEXTURE_FRAME_BUFFER_H + +/* + * Copyright (c) 2019 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 +{ +using Mask = Dali::FrameBuffer::Attachment::Mask; + +namespace Internal +{ +namespace Render +{ +class Texture; + +class TextureFrameBuffer : public FrameBuffer +{ +public: + + /** + * Constructor + * @param[in] width The width of the FrameBuffer + * @param[in] height The height of the FrameBuffer + * @param[in] attachments The attachments comprising the format of the FrameBuffer (bit-mask) + */ + TextureFrameBuffer( uint32_t width, uint32_t height, Mask attachments ); + + /** + * Destructor + */ + virtual ~TextureFrameBuffer(); + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::Initialize() + */ + void Initialize( Context& context ) override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::Destroy() + */ + void Destroy( Context& context ) override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::GlContextDestroyed() + */ + void GlContextDestroyed() override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::Bind() + */ + void Bind( Context& context ) override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::GetWidth() + */ + uint32_t GetWidth() const override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::GetHeight() + */ + uint32_t GetHeight() const override; + + /** + * @copydoc Dali::Internal::Renderer::FrameBuffer::IsSurfaceBacked() + */ + bool IsSurfaceBacked() override { return false; }; + + /** + * @brief Attach a texture for color rendering. Valid only for Framebuffers with COLOR attachments. + * param[in] context The GL context + * @param[in] texture The texture that will be used as output when rendering + * @param[in] mipmapLevel The mipmap of the texture to be attached + * @param[in] layer Indicates which layer of a cube map or array texture to attach. Unused for 2D textures + */ + void AttachColorTexture( Context& context, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer ); + +private: + + GLuint mId; + GLuint mDepthBuffer; + GLuint mStencilBuffer; + uint32_t mWidth; + uint32_t mHeight; +}; + + +} // namespace Render + +} // namespace Internal + +} // namespace Dali + + +#endif // DALI_INTERNAL_RENDER_TEXTURE_FRAME_BUFFER_H diff --git a/dali/internal/render/shaders/program-controller.cpp b/dali/internal/render/shaders/program-controller.cpp index cde611db6..87c268e7e 100644 --- a/dali/internal/render/shaders/program-controller.cpp +++ b/dali/internal/render/shaders/program-controller.cpp @@ -155,6 +155,11 @@ void ProgramController::SetShaderSaver( ShaderSaver& shaderSaver ) mShaderSaver = &shaderSaver; } +void ProgramController::ClearCurrentProgram() +{ + SetCurrentProgram( nullptr ); +} + } // namespace Internal } // namespace Dali diff --git a/dali/internal/render/shaders/program-controller.h b/dali/internal/render/shaders/program-controller.h index 9c3945e1f..25c40caee 100644 --- a/dali/internal/render/shaders/program-controller.h +++ b/dali/internal/render/shaders/program-controller.h @@ -124,6 +124,11 @@ public: // API */ void SetShaderSaver( ShaderSaver& shaderSaver ); + /** + * Clear current cached program + */ + void ClearCurrentProgram(); + private: // From ProgramCache /** diff --git a/dali/internal/update/manager/render-task-processor.cpp b/dali/internal/update/manager/render-task-processor.cpp index 1e12967ea..6c30d5862 100644 --- a/dali/internal/update/manager/render-task-processor.cpp +++ b/dali/internal/update/manager/render-task-processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -237,8 +237,9 @@ bool ProcessTasks( BufferIndex updateBufferIndex, const bool isDefaultRenderTask = isFirstRenderTask; isFirstRenderTask = false; - if( ( !renderToFboEnabled && ( ( !processOffscreen && hasFrameBuffer ) || - ( processOffscreen && !hasFrameBuffer ) ) ) || + const bool isSurfaceBacked = hasFrameBuffer && renderTask.GetFrameBuffer()->IsSurfaceBacked(); + if( ( !renderToFboEnabled && ( ( !processOffscreen && hasFrameBuffer && !isSurfaceBacked ) || + ( processOffscreen && ( !hasFrameBuffer || isSurfaceBacked ) ) ) ) || ( renderToFboEnabled && ( ( processOffscreen && !hasFrameBuffer ) || ( isDefaultRenderTask && processOffscreen ) || ( !isDefaultRenderTask && !processOffscreen && hasFrameBuffer ) ) ) || diff --git a/dali/internal/update/render-tasks/scene-graph-render-task-list.h b/dali/internal/update/render-tasks/scene-graph-render-task-list.h index 116ccd346..bf96442c3 100644 --- a/dali/internal/update/render-tasks/scene-graph-render-task-list.h +++ b/dali/internal/update/render-tasks/scene-graph-render-task-list.h @@ -135,7 +135,7 @@ private: // Messages for RenderTaskList -inline void AddTaskMessage( EventThreadServices& eventThreadServices, RenderTaskList& list, OwnerPointer< RenderTask >& task ) +inline void AddTaskMessage( EventThreadServices& eventThreadServices, const RenderTaskList& list, OwnerPointer< RenderTask >& task ) { // Message has ownership of the RenderTask while in transit from event -> update typedef MessageValue1< RenderTaskList, OwnerPointer< RenderTask > > LocalType; @@ -147,7 +147,7 @@ inline void AddTaskMessage( EventThreadServices& eventThreadServices, RenderTask new (slot) LocalType( &list, &RenderTaskList::AddTask, task ); } -inline void RemoveTaskMessage( EventThreadServices& eventThreadServices, RenderTaskList& list, const RenderTask& constTask ) +inline void RemoveTaskMessage( EventThreadServices& eventThreadServices, const RenderTaskList& list, const RenderTask& constTask ) { // Scene graph thread can destroy this object. RenderTask& task = const_cast< RenderTask& >( constTask ); diff --git a/dali/public-api/actors/camera-actor.h b/dali/public-api/actors/camera-actor.h index 401a0e12d..36cfeef58 100644 --- a/dali/public-api/actors/camera-actor.h +++ b/dali/public-api/actors/camera-actor.h @@ -135,7 +135,8 @@ public: /** * @brief Creates a CameraActor object. * - * Sets the default camera perspective projection for the stage's size. @see SetPerspectiveProjection(). + * @note No default camera perspective projection is set by this method. @see SetPerspectiveProjection(). + * * @SINCE_1_0.0 * @return The newly created camera actor */ @@ -332,12 +333,9 @@ public: * and the Z position of the actor based on the canvas size so that 1 unit in * XY (z=0) plane is 1 pixel on screen. * - * If the canvas size is ZERO, it sets the default camera perspective - * projection for the stage's size. - * * @SINCE_1_0.0 * @param[in] size The canvas size - * @pre If size is non ZERO, \e width and \e height must be greater than zero. + * @pre The canvas size must be greater than zero. * */ void SetPerspectiveProjection( const Size& size ); diff --git a/dali/public-api/object/base-object.cpp b/dali/public-api/object/base-object.cpp index 362bde215..243fe2709 100644 --- a/dali/public-api/object/base-object.cpp +++ b/dali/public-api/object/base-object.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace Dali { @@ -38,20 +39,21 @@ BaseObject::~BaseObject() void BaseObject::RegisterObject() { - Internal::Stage* stage = Internal::Stage::GetCurrent(); - if( stage ) + Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal(); + if ( tls ) { - stage->RegisterObject( this ); + tls->GetEventThreadServices().RegisterObject( this ); } } void BaseObject::UnregisterObject() { + Internal::ThreadLocalStorage* tls = Internal::ThreadLocalStorage::GetInternal(); + // Guard to allow handle destruction after Core has been destroyed - Internal::Stage* stage = Internal::Stage::GetCurrent(); - if( stage ) + if( tls ) { - stage->UnregisterObject( this ); + tls->GetEventThreadServices().UnregisterObject( this ); } }