From d5be622593d4ab0091103b5969232c11fcf653a4 Mon Sep 17 00:00:00 2001 From: Wonsik Jung Date: Thu, 26 Nov 2020 19:47:10 +0900 Subject: [PATCH] Fix the synchronization issue when window is resized or rotated Window position, size and rotaton angle information are in both main and update thread. To complete the works, the information should be synchronized in both main and update thread. In addition, when multiple windows works and one of them resized or rotated, all windows are resized or rotated. For fixing them, this patch has the informations are in the related modules (as Intergration::Scene, SceneGraph::Scene ... ) and are compared. Change-Id: I79f12b8f7e15ce2ae07f161959f3450e65f2f1a0 --- automated-tests/src/dali/utc-Dali-Scene.cpp | 11 ++++ dali/integration-api/core.h | 11 ---- dali/integration-api/scene.cpp | 5 ++ dali/integration-api/scene.h | 6 +++ dali/internal/common/core-impl.cpp | 3 -- dali/internal/event/common/scene-impl.cpp | 19 +++---- dali/internal/event/common/scene-impl.h | 5 ++ dali/internal/render/common/render-manager.cpp | 27 ++-------- dali/internal/render/common/render-manager.h | 13 ----- dali/internal/update/common/scene-graph-scene.cpp | 34 ++++++++++++- dali/internal/update/common/scene-graph-scene.h | 62 +++++++++++++++++++++++ dali/internal/update/manager/update-manager.cpp | 36 ------------- dali/internal/update/manager/update-manager.h | 44 +--------------- 13 files changed, 139 insertions(+), 137 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Scene.cpp b/automated-tests/src/dali/utc-Dali-Scene.cpp index 688f7c3..bbfb401 100644 --- a/automated-tests/src/dali/utc-Dali-Scene.cpp +++ b/automated-tests/src/dali/utc-Dali-Scene.cpp @@ -921,10 +921,18 @@ int UtcDaliSceneSurfaceResizedDefaultSceneViewport(void) auto defaultScene = application.GetScene(); DALI_TEST_CHECK(defaultScene); + // consume the resize flag by first rendering + defaultScene.IsSurfaceRectChanged(); + // Ensure stage size matches the scene size auto stage = Stage::GetCurrent(); DALI_TEST_EQUALS(stage.GetSize(), defaultScene.GetSize(), TEST_LOCATION); + bool surfaceResized; + // check resized flag before surface is resized. + surfaceResized = defaultScene.IsSurfaceRectChanged(); + DALI_TEST_EQUALS(surfaceResized, false, TEST_LOCATION); + // Resize the scene Vector2 newSize(1000.0f, 2000.0f); std::string viewportParams("0, 0, 1000, 2000"); // to match newSize @@ -938,6 +946,9 @@ int UtcDaliSceneSurfaceResizedDefaultSceneViewport(void) application.SendNotification(); application.Render(0); + surfaceResized = defaultScene.IsSurfaceRectChanged(); + DALI_TEST_EQUALS(surfaceResized, true, TEST_LOCATION); + // Check that the viewport is handled properly DALI_TEST_CHECK(callStack.FindMethodAndGetParameters("Viewport", viewportParams)); diff --git a/dali/integration-api/core.h b/dali/integration-api/core.h index 686a1ec..4952c57 100644 --- a/dali/integration-api/core.h +++ b/dali/integration-api/core.h @@ -81,7 +81,6 @@ public: UpdateStatus() : keepUpdating(false), needsNotification(false), - surfaceRectChanged(false), secondsFromLastFrame(0.0f) { } @@ -107,15 +106,6 @@ public: } /** - * Query wheter the default surface rect is changed or not. - * @return true if the default surface rect is changed. - */ - bool SurfaceRectChanged() - { - return surfaceRectChanged; - } - - /** * This method is provided so that FPS can be easily calculated with a release version * of Core. * @return the seconds from last frame as float @@ -128,7 +118,6 @@ public: public: uint32_t keepUpdating; ///< A bitmask of KeepUpdating values bool needsNotification; - bool surfaceRectChanged; float secondsFromLastFrame; }; diff --git a/dali/integration-api/scene.cpp b/dali/integration-api/scene.cpp index 8650fea..bbe1139 100644 --- a/dali/integration-api/scene.cpp +++ b/dali/integration-api/scene.cpp @@ -161,6 +161,11 @@ void Scene::SurfaceRotated(float width, float height, int orientation) GetImplementation(*this).SurfaceRotated(width, height, orientation); } +bool Scene::IsSurfaceRectChanged() const +{ + return GetImplementation(*this).IsSurfaceRectChanged(); +} + Scene::EventProcessingFinishedSignalType& Scene::EventProcessingFinishedSignal() { return GetImplementation(*this).EventProcessingFinishedSignal(); diff --git a/dali/integration-api/scene.h b/dali/integration-api/scene.h index d5920da..eeb191f 100644 --- a/dali/integration-api/scene.h +++ b/dali/integration-api/scene.h @@ -294,6 +294,12 @@ public: void SurfaceRotated(float width, float height, int orientation); /** + * Query wheter the surface rect is changed or not. + * @return true if the surface rect is changed. + */ + bool IsSurfaceRectChanged() const; + + /** * @brief This signal is emitted just after the event processing is finished. * * @return The signal to connect to diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index 9b5c071..41adba0 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -207,9 +207,6 @@ void Core::Update(float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uint // Check the Notification Manager message queue to set needsNotification status.needsNotification = mNotificationManager->MessagesToProcess(); - // Check if the default surface is changed - status.surfaceRectChanged = mUpdateManager->IsDefaultSurfaceRectChanged(); - // No need to keep update running if there are notifications to process. // Any message to update will wake it up anyways } diff --git a/dali/internal/event/common/scene-impl.cpp b/dali/internal/event/common/scene-impl.cpp index 4ab5142..e4aa616 100755 --- a/dali/internal/event/common/scene-impl.cpp +++ b/dali/internal/event/common/scene-impl.cpp @@ -131,14 +131,13 @@ void Scene::Initialize(Size size, int orientation) // Create the default render-task and ensure clear is enabled on it to show the background color RenderTaskPtr renderTask = mRenderTaskList->CreateTask( mRootLayer.Get(), mDefaultCamera.Get() ); renderTask->SetClearEnabled(true); - mSurfaceOrientation = orientation; - - SurfaceRotated( size.width, size.height, mSurfaceOrientation ); // Create scene graph object mSceneObject = new SceneGraph::Scene(); OwnerPointer< SceneGraph::Scene > transferOwnership( const_cast< SceneGraph::Scene* >( mSceneObject ) ); AddSceneMessage( updateManager, transferOwnership ); + + SurfaceRotated( size.width, size.height, orientation ); } void Scene::Add(Actor& actor) @@ -294,7 +293,6 @@ int Scene::GetSurfaceOrientation() void Scene::ChangedSurface(float width, float height, int orientation) { Rect newSize(0, 0, static_cast(width), static_cast(height)); // truncated - mSize.width = width; mSize.height = height; @@ -305,18 +303,21 @@ void Scene::ChangedSurface(float width, float height, int orientation) mRootLayer->SetSize(width, height); + // Send the surface rectangle/orientation to SceneGraph::Scene for calculating glViewport/Scissor ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal(); - SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager(); - SetDefaultSurfaceRectMessage(updateManager, newSize); - - // Send the surface orientation to render manager for calculating glViewport/Scissor - SetDefaultSurfaceOrientationMessage(updateManager, orientation); + SetSurfaceRectMessage(tls->GetEventThreadServices(), *mSceneObject, newSize); + SetSurfaceOrientationMessage(tls->GetEventThreadServices(), *mSceneObject, static_cast(orientation)); // set default render-task viewport parameters RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask(0u); defaultRenderTask->SetViewport(newSize); } +bool Scene::IsSurfaceRectChanged() const +{ + return mSceneObject->IsSurfaceRectChanged(); +} + bool Scene::EmitKeyEventGeneratedSignal(const Dali::KeyEvent& event) { // Emit the KeyEventGenerated signal when KeyEvent is generated diff --git a/dali/internal/event/common/scene-impl.h b/dali/internal/event/common/scene-impl.h index 01e4b47..1346448 100644 --- a/dali/internal/event/common/scene-impl.h +++ b/dali/internal/event/common/scene-impl.h @@ -252,6 +252,11 @@ public: int GetSurfaceOrientation(); /** + * @copydoc Dali::Integration::Scene::IsSurfaceRectChanged + */ + bool IsSurfaceRectChanged() const; + + /** * Used by the EventProcessor to emit key event signals. * @param[in] event The key event. */ diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index f132736..027deb7 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -69,7 +69,6 @@ struct RenderManager::Impl renderAlgorithms(), frameCount(0u), renderBufferIndex(SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX), - defaultSurfaceRect(), rendererContainer(), samplerContainer(), textureContainer(), @@ -78,8 +77,7 @@ struct RenderManager::Impl programController(graphicsController), depthBufferAvailable(depthBufferAvailableParam), stencilBufferAvailable(stencilBufferAvailableParam), - partialUpdateAvailable(partialUpdateAvailableParam), - defaultSurfaceOrientation(0) + partialUpdateAvailable(partialUpdateAvailableParam) { // Create thread pool with just one thread ( there may be a need to create more threads in the future ). threadPool = std::unique_ptr(new Dali::ThreadPool()); @@ -152,8 +150,6 @@ struct RenderManager::Impl uint32_t frameCount; ///< The current frame count BufferIndex renderBufferIndex; ///< The index of the buffer to read from; this is opposite of the "update" buffer - Rect defaultSurfaceRect; ///< Rectangle for the default surface we are rendering to - OwnerContainer rendererContainer; ///< List of owned renderers OwnerContainer samplerContainer; ///< List of owned samplers OwnerContainer textureContainer; ///< List of owned textures @@ -174,8 +170,6 @@ struct RenderManager::Impl std::unique_ptr threadPool; ///< The thread pool Vector boundTextures; ///< The textures bound for rendering Vector textureDependencyList; ///< The dependency list of binded textures - - int defaultSurfaceOrientation; ///< defaultSurfaceOrientation for the default surface we are rendering to }; RenderManager* RenderManager::New(Graphics::Controller& graphicsController, @@ -250,16 +244,6 @@ void RenderManager::SetShaderSaver(ShaderSaver& upstream) mImpl->programController.SetShaderSaver(upstream); } -void RenderManager::SetDefaultSurfaceRect(const Rect& rect) -{ - mImpl->defaultSurfaceRect = rect; -} - -void RenderManager::SetDefaultSurfaceOrientation(int orientation) -{ - mImpl->defaultSurfaceOrientation = orientation; -} - void RenderManager::AddRenderer(OwnerPointer& renderer) { // Initialize the renderer as we are now in render thread @@ -601,7 +585,7 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& bool mCleanOnReturn; }; - Rect surfaceRect = Rect(0, 0, static_cast(scene.GetSize().width), static_cast(scene.GetSize().height)); + Rect surfaceRect = sceneObject->GetSurfaceRect(); // Clean collected dirty/damaged rects on exit if 3d layer or 3d node or other conditions. DamagedRectsCleaner damagedRectCleaner(damagedRects); @@ -822,10 +806,11 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: clearColor = Dali::RenderTask::DEFAULT_CLEAR_COLOR; } - Rect surfaceRect = mImpl->defaultSurfaceRect; + Rect surfaceRect = sceneObject->GetSurfaceRect(); + int32_t surfaceOrientation = sceneObject->GetSurfaceOrientation(); + Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable; Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable; - int surfaceOrientation = sceneInternal.GetSurfaceOrientation(); if(instruction.mFrameBuffer) { @@ -857,8 +842,6 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: mImpl->programController.ClearCurrentProgram(); } } - - surfaceRect = Rect(0, 0, static_cast(scene.GetSize().width), static_cast(scene.GetSize().height)); } // Make sure that GL context must be created diff --git a/dali/internal/render/common/render-manager.h b/dali/internal/render/common/render-manager.h index 0e48c76..e3b2297 100644 --- a/dali/internal/render/common/render-manager.h +++ b/dali/internal/render/common/render-manager.h @@ -120,18 +120,6 @@ public: void SetFrameDeltaTime(float deltaTime); /** - * Returns the rectangle for the default surface (probably the application window). - * @return Rectangle for the surface. - */ - void SetDefaultSurfaceRect(const Rect& rect); - - /** - * Returns the orintation for the default surface (probably the application window). - * @param[in] orientation the surface's orientation. - */ - void SetDefaultSurfaceOrientation(int orientation); - - /** * Add a Renderer to the render manager. * @param[in] renderer The renderer to add. * @post renderer is owned by RenderManager @@ -411,7 +399,6 @@ public: void PostRender(bool uploadOnly); private: -private: /** * Construct a new RenderManager. */ diff --git a/dali/internal/update/common/scene-graph-scene.cpp b/dali/internal/update/common/scene-graph-scene.cpp index fa14393..0d80de2 100644 --- a/dali/internal/update/common/scene-graph-scene.cpp +++ b/dali/internal/update/common/scene-graph-scene.cpp @@ -32,7 +32,10 @@ Scene::Scene() : mContext( nullptr ), mFrameRenderedCallbacks(), mFramePresentedCallbacks(), - mSkipRendering( false ) + mSkipRendering( false ), + mSurfaceRect(), + mSurfaceOrientation( 0 ), + mSurfaceRectChanged( false ) { } @@ -99,6 +102,35 @@ bool Scene::IsRenderingSkipped() const return mSkipRendering; } +void Scene::SetSurfaceRect( const Rect& rect ) +{ + mSurfaceRect = rect; + mSurfaceRectChanged = true; +} + +const Rect& Scene::GetSurfaceRect() const +{ + return mSurfaceRect; +} + +void Scene::SetSurfaceOrientation( int32_t orientation ) +{ + mSurfaceOrientation = orientation; +} + +int32_t Scene::GetSurfaceOrientation() const +{ + return mSurfaceOrientation; +} + +bool Scene::IsSurfaceRectChanged() +{ + bool surfaceRectChanged = mSurfaceRectChanged; + mSurfaceRectChanged = false; + + return surfaceRectChanged; +} + } //SceneGraph } //Internal diff --git a/dali/internal/update/common/scene-graph-scene.h b/dali/internal/update/common/scene-graph-scene.h index 140d49a..230eea5 100644 --- a/dali/internal/update/common/scene-graph-scene.h +++ b/dali/internal/update/common/scene-graph-scene.h @@ -127,6 +127,42 @@ public: */ bool IsRenderingSkipped() const; + /** + * Set the surface rectangle when surface is resized. + * + * @param[in] scene The resized scene. + * @param[in] rect The retangle representing the surface. + */ + void SetSurfaceRect( const Rect& rect ); + + /** + * Get the surface rectangle. + * + * @return the current surface rectangle + */ + const Rect& GetSurfaceRect() const; + + /** + * Set the surface orientation when surface is rotated. + * + * @param[in] scene The rotated scene. + * @param[in] orientation The orientation value representing the surface. + */ + void SetSurfaceOrientation( int32_t orientation ); + + /** + * Get the surface orientation. + * + * @return the current surface orientation + */ + int32_t GetSurfaceOrientation() const; + + /** + * Query wheter the surface rect is changed or not. + * @return true if the surface rect is changed. + */ + bool IsSurfaceRectChanged(); + private: Context* mContext; ///< The context holding the GL state of rendering for the scene, not owned @@ -140,6 +176,10 @@ private: Dali::Integration::Scene::FrameCallbackContainer mFramePresentedCallbacks; ///< Frame presented callbacks bool mSkipRendering; ///< A flag to skip rendering + + Rect mSurfaceRect; ///< The rectangle of surface which is related ot this scene. + int32_t mSurfaceOrientation; ///< The orientation of surface which is related of this scene + bool mSurfaceRectChanged; ///< The flag of surface's rectangle is changed when is resized, moved or rotated. }; /// Messages @@ -165,6 +205,28 @@ inline void AddFramePresentedCallbackMessage( EventThreadServices& eventThreadSe new (slot) LocalType( &scene, &Scene::AddFramePresentedCallback, const_cast< CallbackBase* >( callback ), frameId ); } +inline void SetSurfaceRectMessage( EventThreadServices& eventThreadServices, const Scene& scene, const Rect& rect ) +{ + using LocalType = MessageValue1 >; + + // Reserve some memory inside the message queue + uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) LocalType( &scene, &Scene::SetSurfaceRect, rect ); +} + +inline void SetSurfaceOrientationMessage( EventThreadServices& eventThreadServices, const Scene& scene, int32_t orientation ) +{ + using LocalType = MessageValue1; + + // Reserve some memory inside the message queue + uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) LocalType( &scene, &Scene::SetSurfaceOrientation, orientation ); +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index f60bbdf..171665f 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -189,7 +189,6 @@ struct UpdateManager::Impl previousUpdateScene( false ), renderTaskWaiting( false ), renderersAdded( false ), - surfaceRectChanged( false ), renderingRequired( false ) { sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue ); @@ -298,7 +297,6 @@ struct UpdateManager::Impl bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out) bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing - bool surfaceRectChanged; ///< True if the default surface rect is changed bool renderingRequired; ///< True if required to render the current frame private: @@ -1129,19 +1127,6 @@ uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const return keepUpdatingRequest; } -void UpdateManager::SetDefaultSurfaceRect( const Rect& rect ) -{ - mImpl->surfaceRectChanged = true; - - using DerivedType = MessageValue1 >; - - // Reserve some memory inside the render queue - uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); - - // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect ); -} - void UpdateManager::SurfaceReplaced( Scene* scene ) { using DerivedType = MessageValue1; @@ -1153,17 +1138,6 @@ void UpdateManager::SurfaceReplaced( Scene* scene ) new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SurfaceReplaced, scene ); } -void UpdateManager::SetDefaultSurfaceOrientation(int orientation) -{ - using DerivedType = MessageValue1; - - // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); - - // Construct message in the render queue memory; note that delete should not be called on the return value - new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetDefaultSurfaceOrientation, orientation); -} - void UpdateManager::KeepRendering( float durationSeconds ) { mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds ); @@ -1210,16 +1184,6 @@ void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths ) } } -bool UpdateManager::IsDefaultSurfaceRectChanged() -{ - bool surfaceRectChanged = mImpl->surfaceRectChanged; - - // Reset the flag - mImpl->surfaceRectChanged = false; - - return surfaceRectChanged; -} - void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode ) { mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode ); diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index b966cfc..881b844 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -603,18 +603,6 @@ public: bool isRenderingToFbo); /** - * Set the default surface rect. - * @param[in] rect The rect value representing the surface. - */ - void SetDefaultSurfaceRect(const Rect& rect); - - /** - * Set the default surface orientation. - * @param[in] orientation The orientation value representing the surface. - */ - void SetDefaultSurfaceOrientation(int orientation); - - /** * @copydoc Dali::Stage::KeepRendering() */ void KeepRendering(float durationSeconds); @@ -646,12 +634,6 @@ public: void SetDepthIndices(OwnerPointer& nodeDepths); /** - * Query wheter the default surface rect is changed or not. - * @return true if the default surface rect is changed. - */ - bool IsDefaultSurfaceRectChanged(); - - /** * Adds an implementation of the FrameCallbackInterface. * @param[in] frameCallback An OwnerPointer to the SceneGraph FrameCallback object * @param[in] rootNode A pointer to the root node to apply the FrameCallback to @@ -1048,18 +1030,7 @@ inline void SetShaderProgramMessage(UpdateManager& manager, new(slot) LocalType(&manager, &UpdateManager::SetShaderProgram, const_cast(&shader), shaderData, modifiesGeometry); } -inline void SetDefaultSurfaceRectMessage(UpdateManager& manager, const Rect& rect) -{ - using LocalType = MessageValue1 >; - - // Reserve some memory inside the message queue - uint32_t* slot = manager.ReserveMessageSlot(sizeof(LocalType)); - - // Construct message in the message queue memory; note that delete should not be called on the return value - new(slot) LocalType(&manager, &UpdateManager::SetDefaultSurfaceRect, rect); -} - -inline void SurfaceReplacedMessage(UpdateManager& manager, const SceneGraph::Scene& constScene) +inline void SurfaceReplacedMessage( UpdateManager& manager, const SceneGraph::Scene& constScene ) { // The scene-graph thread owns this object so it can safely edit it. Scene& scene = const_cast(constScene); @@ -1073,18 +1044,7 @@ inline void SurfaceReplacedMessage(UpdateManager& manager, const SceneGraph::Sce new(slot) LocalType(&manager, &UpdateManager::SurfaceReplaced, &scene); } -inline void SetDefaultSurfaceOrientationMessage(UpdateManager& manager, int orientation) -{ - using LocalType = MessageValue1; - - // Reserve some memory inside the message queue - unsigned int* slot = manager.ReserveMessageSlot(sizeof(LocalType)); - - // Construct message in the message queue memory; note that delete should not be called on the return value - new(slot) LocalType(&manager, &UpdateManager::SetDefaultSurfaceOrientation, orientation); -} - -inline void KeepRenderingMessage(UpdateManager& manager, float durationSeconds) +inline void KeepRenderingMessage( UpdateManager& manager, float durationSeconds ) { using LocalType = MessageValue1; -- 2.7.4