From 403f5989d41f4e5c5a657e24020fe32c77fc1414 Mon Sep 17 00:00:00 2001 From: Seoyeon Kim Date: Tue, 12 Mar 2019 14:08:43 +0900 Subject: [PATCH] Revert "[Tizen] Revert "Support multiple window rendering"" This reverts commit c3cc5b3c11dff5a5b0e0cdb7ea929dc2b4314bcc. --- automated-tests/src/dali-internal/CMakeLists.txt | 1 + .../src/dali-internal/utc-Dali-Internal-Core.cpp | 29 --- automated-tests/src/dali/CMakeLists.txt | 2 + .../dali-test-suite-utils/test-application.cpp | 27 +- .../dali/dali-test-suite-utils/test-application.h | 13 +- .../dali-test-suite-utils/test-render-surface.cpp | 115 +++++++++ .../dali-test-suite-utils/test-render-surface.h | 155 +++++++++++ automated-tests/src/dali/utc-Dali-CameraActor.cpp | 22 +- automated-tests/src/dali/utc-Dali-RenderTask.cpp | 65 +++-- automated-tests/src/dali/utc-Dali-Scene.cpp | 158 ++++++++++++ automated-tests/src/dali/utc-Dali-Stage.cpp | 3 +- build/tizen/dali-core/Makefile.am | 1 + dali/integration-api/CMakeLists.txt | 2 + dali/integration-api/core.cpp | 22 +- dali/integration-api/core.h | 35 +-- dali/integration-api/file.list | 5 +- dali/integration-api/render-surface.h | 215 ++++++++++++++++ dali/integration-api/scene.cpp | 119 +++++++++ dali/integration-api/scene.h | 195 ++++++++++++++ dali/internal/CMakeLists.txt | 4 +- dali/internal/common/core-impl.cpp | 135 +++++++--- dali/internal/common/core-impl.h | 121 +++++++-- dali/internal/event/actors/actor-impl.cpp | 52 ++-- dali/internal/event/actors/actor-impl.h | 17 ++ dali/internal/event/actors/camera-actor-impl.cpp | 30 +-- dali/internal/event/actors/camera-actor-impl.h | 5 +- dali/internal/event/actors/layer-impl.cpp | 12 +- dali/internal/event/animation/animation-impl.cpp | 28 +- dali/internal/event/animation/constraint-base.cpp | 5 +- .../event/common/event-thread-services.cpp | 7 +- dali/internal/event/common/event-thread-services.h | 8 +- dali/internal/event/common/object-impl.cpp | 2 +- .../internal/event/common/property-buffer-impl.cpp | 5 +- .../event/common/property-notification-impl.cpp | 22 +- dali/internal/event/common/scene-impl.cpp | 268 ++++++++++++++++++++ dali/internal/event/common/scene-impl.h | 224 ++++++++++++++++ dali/internal/event/common/stage-impl.cpp | 269 ++------------------ dali/internal/event/common/stage-impl.h | 189 +------------- .../internal/event/common/thread-local-storage.cpp | 33 ++- dali/internal/event/common/thread-local-storage.h | 43 +++- .../event/render-tasks/render-task-impl.cpp | 33 ++- .../internal/event/render-tasks/render-task-impl.h | 17 +- .../event/render-tasks/render-task-list-impl.cpp | 12 +- .../event/render-tasks/render-task-list-impl.h | 7 + .../internal/event/rendering/frame-buffer-impl.cpp | 53 +++- dali/internal/event/rendering/frame-buffer-impl.h | 29 ++- dali/internal/event/rendering/geometry-impl.cpp | 6 +- dali/internal/event/rendering/sampler-impl.cpp | 4 +- dali/internal/event/rendering/texture-impl.cpp | 6 +- dali/internal/event/rendering/texture-set-impl.cpp | 5 +- .../size-negotiation/relayout-controller-impl.cpp | 41 +-- .../size-negotiation/relayout-controller-impl.h | 18 +- dali/internal/file.list | 4 +- dali/internal/render/common/render-manager.cpp | 282 +++++++++++++++------ dali/internal/render/gl-resources/gpu-buffer.cpp | 28 +- dali/internal/render/gl-resources/gpu-buffer.h | 9 +- .../render/renderers/render-frame-buffer.h | 55 ++-- dali/internal/render/renderers/render-geometry.cpp | 21 +- dali/internal/render/renderers/render-geometry.h | 19 +- .../render/renderers/render-property-buffer.cpp | 6 +- .../render/renderers/render-property-buffer.h | 3 +- dali/internal/render/renderers/render-renderer.cpp | 17 +- dali/internal/render/renderers/render-renderer.h | 8 +- .../renderers/render-surface-frame-buffer.cpp | 104 ++++++++ .../render/renderers/render-surface-frame-buffer.h | 130 ++++++++++ ...-buffer.cpp => render-texture-frame-buffer.cpp} | 33 +-- .../render/renderers/render-texture-frame-buffer.h | 111 ++++++++ .../internal/render/shaders/program-controller.cpp | 5 + dali/internal/render/shaders/program-controller.h | 5 + .../update/manager/render-task-processor.cpp | 7 +- .../render-tasks/scene-graph-render-task-list.h | 4 +- dali/public-api/actors/camera-actor.h | 8 +- dali/public-api/object/base-object.cpp | 14 +- 73 files changed, 2801 insertions(+), 966 deletions(-) create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp create mode 100644 automated-tests/src/dali/dali-test-suite-utils/test-render-surface.h create mode 100644 automated-tests/src/dali/utc-Dali-Scene.cpp create mode 100644 dali/integration-api/render-surface.h create mode 100644 dali/integration-api/scene.cpp create mode 100644 dali/integration-api/scene.h create mode 100644 dali/internal/event/common/scene-impl.cpp create mode 100644 dali/internal/event/common/scene-impl.h create mode 100644 dali/internal/render/renderers/render-surface-frame-buffer.cpp create mode 100644 dali/internal/render/renderers/render-surface-frame-buffer.h rename dali/internal/render/renderers/{render-frame-buffer.cpp => render-texture-frame-buffer.cpp} (74%) create mode 100644 dali/internal/render/renderers/render-texture-frame-buffer.h diff --git a/automated-tests/src/dali-internal/CMakeLists.txt b/automated-tests/src/dali-internal/CMakeLists.txt index 64b34e7..2566323 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 e12a27a..99c55b8 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 288073d..62bad22 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 c953f50..1562d27 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 d1e042d..fc2929c 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 0000000..332d77e --- /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 0000000..fba89c2 --- /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 415f6cf..ac726f7 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 b784e1a..6c6197d 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 0000000..a8b706e --- /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 954957f..a3fb8f2 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 c9f9f07..9242d3b 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 76346b5..a856c3b 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 de8714f..b14df7c 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 f7e11b7..45d7582 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 e778e61..db6517c 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 0000000..17f22e9 --- /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 0000000..717132c --- /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 0000000..83519b6 --- /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 38cfe06..47d1722 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 7d6f523..4ddbc04 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 d4aa55f..bd94c43 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: @@ -91,6 +96,11 @@ public: ~Core(); /** + * @copydoc Dali::Integration::Core::Initialize() + */ + void Initialize(); + + /** * @copydoc Dali::Integration::Core::GetContextNotifier() */ Integration::ContextNotifierInterface* 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 @@ -191,12 +243,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 d2b33c9..a3504e5 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 c98701a..9a27d81 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 3d21383..ae63c9f 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 dc017f8..1694ba3 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 033ee7b..8040640 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 587a96a..876ec29 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 8ebbd6e..c70b251 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 66e87e9..aa9e334 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 8089950..b6db047 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. @@ -58,6 +58,12 @@ public: { } /** + * Get the EventThreadServices + * @return reference to the EventThreadServices + */ + static EventThreadServices& Get(); + + /** * @brief Registers the object as created with the Object registry. * * @param[in] object to register diff --git a/dali/internal/event/common/object-impl.cpp b/dali/internal/event/common/object-impl.cpp index 09e48c0..d6c5cea 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 ecd9a69..c44df2c 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 a261fa2..7e407ca 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 0000000..f68060e --- /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 0000000..1140b6a --- /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 8294cf8..54201e1 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 493c346..1f52431 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 /** @@ -140,22 +116,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 * The y component will be the height of the Stage in pixels @@ -169,16 +129,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 /** @@ -252,17 +181,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() */ void KeepRendering( float durationSeconds ); @@ -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 559b833..1eab332 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 95b6c30..0e6e400 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 14bc16b..aeec93f 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 de111d0..45e59ea 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 c3a40d6..eb4bbf6 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 55e37e8..9f203d8 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 ccfc8d0..fd5f4bf 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 9389193..3531c0f 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 @@ -55,6 +61,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 * * @return 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 0897c08..57469e5 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 d6e8af0..79d1185 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 3c3bbbd..3fb61f7 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 349eaa6..7c562e4 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 35190fe..87d8645 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 543ae66..5f7fb1f 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. @@ -68,13 +68,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. * * This flags the actor and all actors dependent on it for relayout. The actual @@ -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 367a424..c007a04 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 e9e13e8..a69d02f 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 257b12a..9b8799f 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 7c32719..662a180 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.h b/dali/internal/render/renderers/render-frame-buffer.h index 196630d..16d2a73 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 afc96ba..17ba522 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 4e12e1c..f08cbce 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 5197837..5976020 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 436bd06..13771f5 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 4beee2e..2222abd 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 1f8d99e..66e33aa 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. @@ -335,6 +335,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 * @param[in] bufferIndex The index of the previous update buffer. 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 0000000..7cc38bb --- /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 0000000..576ea65 --- /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-frame-buffer.cpp b/dali/internal/render/renderers/render-texture-frame-buffer.cpp similarity index 74% rename from dali/internal/render/renderers/render-frame-buffer.cpp rename to dali/internal/render/renderers/render-texture-frame-buffer.cpp index 2ea746e..9e3120e 100644 --- a/dali/internal/render/renderers/render-frame-buffer.cpp +++ b/dali/internal/render/renderers/render-texture-frame-buffer.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. @@ -15,7 +15,7 @@ */ // CLASS HEADER -#include +#include // INTERNAL INCLUDES #include @@ -27,19 +27,20 @@ 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 ) +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 ) { } -FrameBuffer::~FrameBuffer() +TextureFrameBuffer::~TextureFrameBuffer() {} -void FrameBuffer::Destroy( Context& context ) +void TextureFrameBuffer::Destroy( Context& context ) { if( mId ) { @@ -47,12 +48,12 @@ void FrameBuffer::Destroy( Context& context ) } } -void FrameBuffer::GlContextDestroyed() +void TextureFrameBuffer::GlContextDestroyed() { mId = 0u; } -void FrameBuffer::Initialize(Context& context) +void TextureFrameBuffer::Initialize(Context& context) { context.GenFramebuffers( 1, &mId ); context.BindFramebuffer( GL_FRAMEBUFFER, mId ); @@ -78,7 +79,7 @@ void FrameBuffer::Initialize(Context& context) context.BindFramebuffer( GL_FRAMEBUFFER, 0 ); } -void FrameBuffer::AttachColorTexture( Context& context, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer ) +void TextureFrameBuffer::AttachColorTexture( Context& context, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer ) { context.BindFramebuffer( GL_FRAMEBUFFER, mId ); @@ -103,17 +104,17 @@ void FrameBuffer::AttachColorTexture( Context& context, Render::Texture* texture context.BindFramebuffer( GL_FRAMEBUFFER, 0 ); } -void FrameBuffer::Bind( Context& context ) +void TextureFrameBuffer::Bind( Context& context ) { context.BindFramebuffer( GL_FRAMEBUFFER, mId ); } -uint32_t FrameBuffer::GetWidth() const +uint32_t TextureFrameBuffer::GetWidth() const { return mWidth; } -uint32_t FrameBuffer::GetHeight() const +uint32_t TextureFrameBuffer::GetHeight() const { return mHeight; } 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 0000000..021890f --- /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 cde611d..87c268e 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 9c3945e..25c40ca 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 1e12967..6c30d58 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 116ccd3..bf96442 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 401a0e1..36cfeef 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 362bde2..243fe27 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 ); } } -- 2.7.4