From d2bc18872d7b4f316b86a0897e6c9fabf67a1241 Mon Sep 17 00:00:00 2001 From: Wonsik Jung Date: Fri, 14 Jun 2019 14:46:43 +0900 Subject: [PATCH] [Tizen] Support Client Rotation and Screen Rotation Change-Id: I1a1914e7ef798e5d60ddb69a25a5c69e996836c4 --- .../dali-test-suite-utils/test-application.cpp | 4 +- .../dali-test-suite-utils/test-render-surface.cpp | 5 ++ .../dali-test-suite-utils/test-render-surface.h | 5 ++ dali/integration-api/core.cpp | 4 +- dali/integration-api/core.h | 3 +- dali/integration-api/render-surface.h | 6 ++ dali/integration-api/scene.cpp | 4 +- dali/integration-api/scene.h | 2 +- dali/internal/common/core-impl.cpp | 4 +- dali/internal/common/core-impl.h | 4 +- dali/internal/event/actors/camera-actor-impl.cpp | 6 ++ dali/internal/event/actors/camera-actor-impl.h | 7 ++ dali/internal/event/common/scene-impl.cpp | 17 +++-- dali/internal/event/common/scene-impl.h | 7 +- dali/internal/render/common/render-algorithms.cpp | 77 +++++++++++++++++++--- dali/internal/render/common/render-algorithms.h | 11 ++-- dali/internal/render/common/render-instruction.h | 2 +- dali/internal/render/common/render-manager.cpp | 26 ++++++-- dali/internal/render/common/render-manager.h | 6 ++ dali/internal/update/manager/update-manager.cpp | 11 ++++ dali/internal/update/manager/update-manager.h | 17 +++++ .../update/render-tasks/scene-graph-camera.cpp | 47 ++++++++++++- .../update/render-tasks/scene-graph-camera.h | 25 +++++++ 23 files changed, 263 insertions(+), 37 deletions(-) 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 0b98b27..322588e 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 @@ -64,11 +64,11 @@ void TestApplication::Initialize() 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.SetSurface( *mRenderSurface, false ); mScene.SetDpi( Vector2( static_cast( mDpi.x ), static_cast( mDpi.y ) ) ); - mCore->SurfaceResized( mRenderSurface ); + mCore->SurfaceResized( mRenderSurface, false ); mCore->SceneCreated(); mCore->Initialize(); 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 index 332d77e..066b37e 100644 --- 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 @@ -40,6 +40,11 @@ void TestRenderSurface::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVe dpiHorizontal = dpiVertical = 96; }; +int TestRenderSurface::GetOrientation() const +{ + return 0; +}; + void TestRenderSurface::InitializeGraphics() { } 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 index fba89c2..be38d00 100644 --- 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 @@ -53,6 +53,11 @@ public: virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ); /** + * @copydoc Dali::Integration::RenderSurface::GetOrientation + */ + virtual int GetOrientation() const; + + /** * @copydoc Dali::Integration::RenderSurface::InitializeGraphics */ virtual void InitializeGraphics(); diff --git a/dali/integration-api/core.cpp b/dali/integration-api/core.cpp index 596ef9a..0d265f6 100644 --- a/dali/integration-api/core.cpp +++ b/dali/integration-api/core.cpp @@ -86,9 +86,9 @@ void Core::RecoverFromContextLoss() mImpl->RecoverFromContextLoss(); } -void Core::SurfaceResized( Integration::RenderSurface* surface ) +void Core::SurfaceResized( Integration::RenderSurface* surface, bool forceUpdate ) { - mImpl->SurfaceResized(surface); + mImpl->SurfaceResized(surface, forceUpdate); } void Core::SurfaceDeleted( Integration::RenderSurface* surface ) diff --git a/dali/integration-api/core.h b/dali/integration-api/core.h index ff62bcb..97b6e7a 100644 --- a/dali/integration-api/core.h +++ b/dali/integration-api/core.h @@ -291,8 +291,9 @@ public: * 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] surface The resized surface + * @param[in] forceUpate The flag is for update force */ - void SurfaceResized( Integration::RenderSurface* surface ); + void SurfaceResized( Integration::RenderSurface* surface, bool fourceUpdate ); /** * Notify the Core that the GL surface has been deleted. diff --git a/dali/integration-api/render-surface.h b/dali/integration-api/render-surface.h index 2270fc2..b0a3b37 100644 --- a/dali/integration-api/render-surface.h +++ b/dali/integration-api/render-surface.h @@ -103,6 +103,12 @@ public: virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) = 0; /** + * @brief Return the orientation of the surface. + * @return The orientation + */ + virtual int GetOrientation() const = 0; + + /** * @brief InitializeGraphics the platform specific graphics surface interfaces */ virtual void InitializeGraphics() = 0; diff --git a/dali/integration-api/scene.cpp b/dali/integration-api/scene.cpp index 9331a99..9f9350b 100644 --- a/dali/integration-api/scene.cpp +++ b/dali/integration-api/scene.cpp @@ -119,9 +119,9 @@ Layer Scene::GetLayer( uint32_t depth ) const return GetImplementation(*this).GetLayer( depth ); } -void Scene::SetSurface( Integration::RenderSurface& surface ) +void Scene::SetSurface( Integration::RenderSurface& surface, bool forceUpdate ) { - GetImplementation(*this).SetSurface( surface ); + GetImplementation(*this).SetSurface( surface, forceUpdate ); } Integration::RenderSurface* Scene::GetSurface() const diff --git a/dali/integration-api/scene.h b/dali/integration-api/scene.h index 1d82a44..ad8769d 100755 --- a/dali/integration-api/scene.h +++ b/dali/integration-api/scene.h @@ -200,7 +200,7 @@ public: * * @return The root layer */ - void SetSurface( Integration::RenderSurface& surface ); + void SetSurface( Integration::RenderSurface& surface, bool forceUpdate ); /** * @brief Gets the rendering surface bound to the scene diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index b906d8f..7412b9a 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -191,13 +191,13 @@ void Core::ContextDestroyed() mRenderManager->ContextDestroyed(); } -void Core::SurfaceResized( Integration::RenderSurface* surface ) +void Core::SurfaceResized( Integration::RenderSurface* surface, bool forceUpdate ) { for( auto iter = mScenes.begin(); iter != mScenes.end(); ++iter ) { if( (*iter)->GetSurface() == surface ) { - (*iter)->SurfaceResized(); + (*iter)->SurfaceResized( forceUpdate ); } } } diff --git a/dali/internal/common/core-impl.h b/dali/internal/common/core-impl.h index 21e0a74..a97d8b1 100644 --- a/dali/internal/common/core-impl.h +++ b/dali/internal/common/core-impl.h @@ -119,9 +119,9 @@ public: void RecoverFromContextLoss(); /** - * @copydoc Dali::Integration::Core::SurfaceResized(Integration::RenderSurface*) + * @copydoc Dali::Integration::Core::SurfaceResized(Integration::RenderSurface*, bool) */ - void SurfaceResized( Integration::RenderSurface* surface ); + void SurfaceResized( Integration::RenderSurface* surface, bool forceUpdate ); /** * @copydoc Dali::Integration::Core::SurfaceDeleted(Integration::RenderSurface*) diff --git a/dali/internal/event/actors/camera-actor-impl.cpp b/dali/internal/event/actors/camera-actor-impl.cpp index ae63c9f..715781e 100644 --- a/dali/internal/event/actors/camera-actor-impl.cpp +++ b/dali/internal/event/actors/camera-actor-impl.cpp @@ -502,6 +502,12 @@ const SceneGraph::Camera* CameraActor::GetCamera() const return mSceneObject; } +void CameraActor::RotateProjection( int rotationAngle ) +{ + // sceneObject is being used in a separate thread; queue a message to set + RotateProjectionMessage( GetEventThreadServices(), *mSceneObject, rotationAngle ); +} + void CameraActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue ) { if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT) diff --git a/dali/internal/event/actors/camera-actor-impl.h b/dali/internal/event/actors/camera-actor-impl.h index 1694ba3..56a39e5 100644 --- a/dali/internal/event/actors/camera-actor-impl.h +++ b/dali/internal/event/actors/camera-actor-impl.h @@ -195,6 +195,13 @@ public: */ const SceneGraph::Camera* GetCamera() const; + /** + * Rotate the projection. + * It is used in case that the target buffer direction is different from the window direction. + * @param [in] rotationAngle The rotation angle + */ + void RotateProjection( int rotationAngle ); + public: // properties /** diff --git a/dali/internal/event/common/scene-impl.cpp b/dali/internal/event/common/scene-impl.cpp index 4b53d79..a157ae7 100644 --- a/dali/internal/event/common/scene-impl.cpp +++ b/dali/internal/event/common/scene-impl.cpp @@ -64,6 +64,7 @@ Scene::Scene( const Size& size ) mSurfaceSize( Vector2::ZERO ), mDpi( Vector2::ZERO ), mBackgroundColor( DEFAULT_BACKGROUND_COLOR ), + mSurfaceOrientation( 0 ), mDepthTreeDirty( false ), mEventProcessor( *this, ThreadLocalStorage::GetInternal()->GetGestureEventProcessor() ) { @@ -196,7 +197,7 @@ Actor& Scene::GetDefaultRootActor() return *mRootLayer; } -void Scene::SetSurface( Integration::RenderSurface& surface ) +void Scene::SetSurface( Integration::RenderSurface& surface, bool forceUpdate ) { mSurface = &surface; if ( mSurface ) @@ -206,18 +207,22 @@ void Scene::SetSurface( Integration::RenderSurface& surface ) mFrameBuffer = Dali::Internal::FrameBuffer::New( surface, Dali::FrameBuffer::Attachment::NONE ); defaultRenderTask->SetFrameBuffer( mFrameBuffer ); - SurfaceResized(); + SurfaceResized( forceUpdate ); } } -void Scene::SurfaceResized() +void Scene::SurfaceResized( bool forceUpdate ) { if( mSurface ) { const float fWidth = static_cast( mSurface->GetPositionSize().width ); const float fHeight = static_cast( mSurface->GetPositionSize().height ); + const int orientation = mSurface->GetOrientation(); - if( ( fabsf( mSurfaceSize.width - fWidth ) > Math::MACHINE_EPSILON_1 ) || ( fabsf( mSurfaceSize.height - fHeight ) > Math::MACHINE_EPSILON_1 ) ) + if( ( fabsf( mSurfaceSize.width - fWidth ) > Math::MACHINE_EPSILON_1 ) + || ( fabsf( mSurfaceSize.height - fHeight ) > Math::MACHINE_EPSILON_1 ) + || ( orientation != mSurfaceOrientation ) + || (forceUpdate) ) { Rect newSize( 0, 0, static_cast( mSurface->GetPositionSize().width ), static_cast( mSurface->GetPositionSize().height ) ); @@ -227,14 +232,18 @@ void Scene::SurfaceResized() mSize.width = mSurfaceSize.width; mSize.height = mSurfaceSize.height; + mSurfaceOrientation = orientation; + // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position. mDefaultCamera->SetPerspectiveProjection( mSurfaceSize ); + mDefaultCamera->RotateProjection( mSurfaceOrientation ); mRootLayer->SetSize( mSize.width, mSize.height ); ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal(); SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager(); SetDefaultSurfaceRectMessage( updateManager, newSize ); // truncated + SetDefaultSurfaceOrientationMessage( updateManager, mSurfaceOrientation ); RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask( 0u ); diff --git a/dali/internal/event/common/scene-impl.h b/dali/internal/event/common/scene-impl.h index c524d62..d048099 100644 --- a/dali/internal/event/common/scene-impl.h +++ b/dali/internal/event/common/scene-impl.h @@ -117,12 +117,12 @@ public: /** * @copydoc Dali::Integration::Scene::SetSurface */ - void SetSurface( Integration::RenderSurface& surface ); + void SetSurface( Integration::RenderSurface& surface, bool forceUpdate ); /** * Notify the surface has been resized. */ - void SurfaceResized(); + void SurfaceResized( bool forceUpdate ); /** * Notify the surface has been deleted. @@ -287,6 +287,9 @@ private: Vector4 mBackgroundColor; + // The SurfaceOrientation + int mSurfaceOrientation; + LayerPtr mRootLayer; // Ordered list of currently on-stage layers diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp index 1d80991..6eb4b50 100644 --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -231,7 +231,7 @@ inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool dep * @param[in] item The current RenderItem about to be rendered * @param[in] context The context */ -inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Context& context ) +inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Context& context, int orientation ) { // Get the number of child scissors in the stack (do not include layer or root box). size_t childStackDepth = mScissorStack.size() - 1u; @@ -292,7 +292,30 @@ inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Cont if( scissorEnabled ) { ClippingBox useScissorBox( mScissorStack.back() ); - context.Scissor( useScissorBox.x, useScissorBox.y, useScissorBox.width, useScissorBox.height ); + GLint x = useScissorBox.x; + GLint y = useScissorBox.y; + if( orientation == 90 ) + { + x = mViewportRectangle.height - (useScissorBox.y + useScissorBox.height); + y = useScissorBox.x; + context.Scissor( x, y, useScissorBox.height, useScissorBox.width ); + } + else if( orientation == 180 ) + { + x = mViewportRectangle.width - (useScissorBox.x + useScissorBox.width); + y = mViewportRectangle.height - (useScissorBox.y + useScissorBox.height); + context.Scissor( x, y, useScissorBox.width, useScissorBox.height ); + } + else if( orientation == 270 ) + { + x = useScissorBox.y; + y = mViewportRectangle.width - (useScissorBox.x + useScissorBox.width); + context.Scissor( x, y, useScissorBox.height, useScissorBox.width ); + } + else + { + context.Scissor( x, y, useScissorBox.width, useScissorBox.height ); + } } } } @@ -302,7 +325,8 @@ inline void RenderAlgorithms::SetupClipping( const RenderItem& item, bool& usedStencilBuffer, uint32_t& lastClippingDepth, uint32_t& lastClippingId, - Integration::StencilBufferAvailable stencilBufferAvailable ) + Integration::StencilBufferAvailable stencilBufferAvailable, + int orientation ) { RenderMode::Type renderMode = RenderMode::AUTO; const Renderer *renderer = item.mRenderer; @@ -324,7 +348,7 @@ inline void RenderAlgorithms::SetupClipping( const RenderItem& item, // As both scissor and stencil clips can be nested, we may be simultaneously traversing up the scissor tree, requiring a scissor to be un-done. Whilst simultaneously adding a new stencil clip. // We process both based on our current and old clipping depths for each mode. // Both methods with return rapidly if there is nothing to be done for that type of clipping. - SetupScissorClipping( item, context ); + SetupScissorClipping( item, context, orientation ); if( stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE ) { @@ -389,7 +413,8 @@ inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList, const Matrix& viewMatrix, const Matrix& projectionMatrix, Integration::DepthBufferAvailable depthBufferAvailable, - Integration::StencilBufferAvailable stencilBufferAvailable ) + Integration::StencilBufferAvailable stencilBufferAvailable, + int orientation ) { DALI_PRINT_RENDER_LIST( renderList ); @@ -406,13 +431,45 @@ inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList, mViewportRectangle = context.GetViewport(); mHasLayerScissor = false; + if( orientation == 90 || orientation == 270 ) + { + int temp = mViewportRectangle.width; + mViewportRectangle.width = mViewportRectangle.height; + mViewportRectangle.height = temp; + } + // Setup Scissor testing (for both viewport and per-node scissor) mScissorStack.clear(); if( renderList.IsClipping() ) { context.SetScissorTest( true ); const ClippingBox& layerScissorBox = renderList.GetClippingBox(); - context.Scissor( layerScissorBox.x, layerScissorBox.y, layerScissorBox.width, layerScissorBox.height ); + GLint x = layerScissorBox.x; + GLint y = layerScissorBox.y; + + if( orientation == 90 ) + { + x = mViewportRectangle.height - (layerScissorBox.y + layerScissorBox.height); + y = layerScissorBox.x; + context.Scissor( x, y, layerScissorBox.height, layerScissorBox.width ); + } + else if( orientation == 180 ) + { + x = mViewportRectangle.width - (layerScissorBox.x + layerScissorBox.width); + y = mViewportRectangle.height - (layerScissorBox.y + layerScissorBox.height); + context.Scissor( x, y, layerScissorBox.width, layerScissorBox.height ); + } + else if( orientation == 270 ) + { + x = layerScissorBox.y; + y = mViewportRectangle.width - (layerScissorBox.x + layerScissorBox.width); + context.Scissor( x, y, layerScissorBox.height, layerScissorBox.width ); + } + else + { + context.Scissor( x, y, layerScissorBox.width, layerScissorBox.height ); + } + mScissorStack.push_back( layerScissorBox ); mHasLayerScissor = true; } @@ -431,7 +488,7 @@ inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList, // Set up clipping based on both the Renderer and Actor APIs. // The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used. - SetupClipping( item, context, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable ); + SetupClipping( item, context, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, orientation ); if( DALI_LIKELY( item.mRenderer ) ) { @@ -462,7 +519,8 @@ void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instru Context& context, BufferIndex bufferIndex, Integration::DepthBufferAvailable depthBufferAvailable, - Integration::StencilBufferAvailable stencilBufferAvailable ) + Integration::StencilBufferAvailable stencilBufferAvailable, + int orientation ) { DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex ); @@ -490,7 +548,8 @@ void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instru *viewMatrix, *projectionMatrix, depthBufferAvailable, - stencilBufferAvailable ); + stencilBufferAvailable, + orientation ); } } } diff --git a/dali/internal/render/common/render-algorithms.h b/dali/internal/render/common/render-algorithms.h index 523cc14..4dfab2c 100644 --- a/dali/internal/render/common/render-algorithms.h +++ b/dali/internal/render/common/render-algorithms.h @@ -63,7 +63,8 @@ class RenderAlgorithms Context& context, BufferIndex bufferIndex, Integration::DepthBufferAvailable depthBufferAvailable, - Integration::StencilBufferAvailable stencilBufferAvailable ); + Integration::StencilBufferAvailable stencilBufferAvailable, + int orientation); private: @@ -86,7 +87,7 @@ class RenderAlgorithms * @param[in] item The current RenderItem (about to be rendered) * @param[in] context The current Context */ - inline void SetupScissorClipping( const Dali::Internal::SceneGraph::RenderItem& item, Context& context ); + inline void SetupScissorClipping( const Dali::Internal::SceneGraph::RenderItem& item, Context& context, int orientation ); /** * @brief Set up the clipping based on the specified clipping settings. @@ -102,7 +103,8 @@ class RenderAlgorithms bool& usedStencilBuffer, uint32_t& lastClippingDepth, uint32_t& lastClippingId, - Integration::StencilBufferAvailable stencilBufferAvailable ); + Integration::StencilBufferAvailable stencilBufferAvailable, + int orientation ); /** * @brief Process a render-list. @@ -120,7 +122,8 @@ class RenderAlgorithms const Matrix& viewMatrix, const Matrix& projectionMatrix, Integration::DepthBufferAvailable depthBufferAvailable, - Integration::StencilBufferAvailable stencilBufferAvailable ); + Integration::StencilBufferAvailable stencilBufferAvailable, + int orientation ); // Prevent copying: RenderAlgorithms( RenderAlgorithms& rhs ); diff --git a/dali/internal/render/common/render-instruction.h b/dali/internal/render/common/render-instruction.h index 3157f85..3d0d64b 100644 --- a/dali/internal/render/common/render-instruction.h +++ b/dali/internal/render/common/render-instruction.h @@ -121,7 +121,7 @@ public: const Matrix* GetProjectionMatrix( BufferIndex index ) const { // inlined as this is called once per frame per render instruction - return &mCamera->GetProjectionMatrix( index ); + return &mCamera->GetFinalProjectionMatrix( index ); } private: diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 2d550b5..086c553 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -84,7 +84,8 @@ struct RenderManager::Impl lastFrameWasRendered( false ), programController( glAbstraction ), depthBufferAvailable( depthBufferAvailableParam ), - stencilBufferAvailable( stencilBufferAvailableParam ) + stencilBufferAvailable( stencilBufferAvailableParam ), + defaultSurfaceOrientation( 0 ) { } @@ -159,6 +160,8 @@ struct RenderManager::Impl Integration::DepthBufferAvailable depthBufferAvailable; ///< Whether the depth buffer is available Integration::StencilBufferAvailable stencilBufferAvailable; ///< Whether the stencil buffer is available + int defaultSurfaceOrientation; ///< defaultSurfaceOrientation for the default surface we are rendering to + }; RenderManager* RenderManager::New( Integration::GlAbstraction& glAbstraction, @@ -242,6 +245,11 @@ void RenderManager::SetDefaultSurfaceRect(const Rect& rect) mImpl->defaultSurfaceRect = rect; } +void RenderManager::SetDefaultSurfaceOrientation( int orientation ) +{ + mImpl->defaultSurfaceOrientation = orientation; +} + void RenderManager::AddRenderer( OwnerPointer< Render::Renderer >& renderer ) { // Initialize the renderer as we are now in render thread @@ -572,6 +580,7 @@ void RenderManager::DoRender( RenderInstruction& instruction ) } Rect surfaceRect = mImpl->defaultSurfaceRect; + int surfaceOrientation = mImpl->defaultSurfaceOrientation; Vector4 backgroundColor = mImpl->backgroundColor; Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable; Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable; @@ -668,7 +677,7 @@ void RenderManager::DoRender( RenderInstruction& instruction ) // 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 ); + viewportRect.Set( instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height ); } else { @@ -687,6 +696,7 @@ void RenderManager::DoRender( RenderInstruction& instruction ) { viewportRect.Set( 0, 0, instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight() ); } + surfaceOrientation = 0; } } else // No Offscreen frame buffer rendering @@ -698,7 +708,7 @@ void RenderManager::DoRender( RenderInstruction& instruction ) { // 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 ); + viewportRect.Set( instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height ); } else { @@ -711,6 +721,13 @@ void RenderManager::DoRender( RenderInstruction& instruction ) } } + if ( surfaceOrientation == 90 || surfaceOrientation == 270 ) + { + int temp = viewportRect.width; + viewportRect.width = viewportRect.height; + viewportRect.height = temp; + } + mImpl->currentContext->Viewport(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height); if ( instruction.mIsClearColorSet ) @@ -733,7 +750,8 @@ void RenderManager::DoRender( RenderInstruction& instruction ) *mImpl->currentContext, mImpl->renderBufferIndex, depthBufferAvailable, - stencilBufferAvailable ); + stencilBufferAvailable, + surfaceOrientation ); if( instruction.mRenderTracker && ( instruction.mFrameBuffer != 0 ) ) { diff --git a/dali/internal/render/common/render-manager.h b/dali/internal/render/common/render-manager.h index aceece5..9196765 100644 --- a/dali/internal/render/common/render-manager.h +++ b/dali/internal/render/common/render-manager.h @@ -138,6 +138,12 @@ public: void SetDefaultSurfaceRect( const Rect& rect ); /** + * Returns the orintation for the default surface (probably the application window). + * @return Orientation for the surface. + */ + void SetDefaultSurfaceOrientation( int orientation ); + + /** * Add a Renderer to the render manager. * @param[in] renderer The renderer to add. * @post renderer is owned by RenderManager diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 852d5d4..571e8b3 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -1103,6 +1103,17 @@ void UpdateManager::SetDefaultSurfaceRect( const Rect& rect ) new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect ); } +void UpdateManager::SetDefaultSurfaceOrientation( int orientation ) +{ + typedef MessageValue1< RenderManager, int > DerivedType; + + // 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 ); diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 039e054..3983bdb 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -606,6 +606,12 @@ public: 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 ); @@ -1030,6 +1036,17 @@ inline void SetDefaultSurfaceRectMessage( UpdateManager& manager, const Rect LocalType; + + // 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 ) { typedef MessageValue1< UpdateManager, float > LocalType; diff --git a/dali/internal/update/render-tasks/scene-graph-camera.cpp b/dali/internal/update/render-tasks/scene-graph-camera.cpp index f6ecce5..7aca9cb 100644 --- a/dali/internal/update/render-tasks/scene-graph-camera.cpp +++ b/dali/internal/update/render-tasks/scene-graph-camera.cpp @@ -157,6 +157,7 @@ const Vector3 Camera::DEFAULT_TARGET_POSITION( 0.0f, 0.0f, 0.0f ); Camera::Camera() : mUpdateViewFlag( UPDATE_COUNT ), mUpdateProjectionFlag( UPDATE_COUNT ), + mProjectionRotation( 0 ), mNode( NULL ), mType( DEFAULT_TYPE ), mProjectionMode( DEFAULT_MODE ), @@ -172,7 +173,8 @@ Camera::Camera() mTargetPosition( DEFAULT_TARGET_POSITION ), mViewMatrix(), mProjectionMatrix(), - mInverseViewProjection( Matrix::IDENTITY ) + mInverseViewProjection( Matrix::IDENTITY ), + mFinalProjection( Matrix::IDENTITY ) { } @@ -261,6 +263,12 @@ void Camera::SetTargetPosition( const Vector3& targetPosition ) mUpdateViewFlag = UPDATE_COUNT; } +void Camera::RotateProjection( int rotationAngle ) +{ + mProjectionRotation = rotationAngle; + mUpdateViewFlag = UPDATE_COUNT; +} + const Matrix& Camera::GetProjectionMatrix( BufferIndex bufferIndex ) const { return mProjectionMatrix[ bufferIndex ]; @@ -276,6 +284,11 @@ const Matrix& Camera::GetInverseViewProjectionMatrix( BufferIndex bufferIndex ) return mInverseViewProjection[ bufferIndex ]; } +const Matrix& Camera::GetFinalProjectionMatrix( BufferIndex bufferIndex ) const +{ + return mFinalProjection[ bufferIndex ]; +} + const PropertyInputImpl* Camera::GetProjectionMatrix() const { return &mProjectionMatrix; @@ -508,6 +521,38 @@ uint32_t Camera::UpdateProjection( BufferIndex updateBufferIndex ) } mProjectionMatrix.SetDirty( updateBufferIndex ); + + Matrix &finalProjection = mFinalProjection[ updateBufferIndex ]; + finalProjection.SetIdentity(); + + Quaternion rotationAngle; + switch( mProjectionRotation ) + { + case 90: + { + rotationAngle = Quaternion( Dali::ANGLE_90, Vector3::ZAXIS ); + break; + } + case 180: + { + rotationAngle = Quaternion( Dali::ANGLE_180, Vector3::ZAXIS ); + break; + } + case 270: + { + rotationAngle = Quaternion( Dali::ANGLE_270, Vector3::ZAXIS ); + break; + } + default: + rotationAngle = Quaternion( Dali::ANGLE_0, Vector3::ZAXIS ); + break; + } + + Matrix rotation; + rotation.SetIdentity(); + rotation.SetTransformComponents( Vector3( 1.0f, 1.0f, 1.0f ), rotationAngle, Vector3( 0.0f, 0.0f, 0.0f ) ); + + Matrix::Multiply( finalProjection, mProjectionMatrix.Get( updateBufferIndex ), rotation ); } --mUpdateProjectionFlag; } diff --git a/dali/internal/update/render-tasks/scene-graph-camera.h b/dali/internal/update/render-tasks/scene-graph-camera.h index d17120f..37aead6 100644 --- a/dali/internal/update/render-tasks/scene-graph-camera.h +++ b/dali/internal/update/render-tasks/scene-graph-camera.h @@ -155,6 +155,11 @@ public: void SetFarClippingPlane( float farClippingPlane ); /** + * @copydoc Dali::Internal::CameraActor::RotateProjection + */ + void RotateProjection( int rotationAngle ); + + /** * @copydoc Dali::Internal::CameraActor::SetTarget */ void SetTargetPosition( const Vector3& targetPosition ); @@ -203,6 +208,13 @@ public: const Matrix& GetInverseViewProjectionMatrix( BufferIndex bufferIndex ) const; /** + * Retrieve the final projection-matrix; this is double buffered for input handling. + * @param[in] bufferIndex The buffer to read from. + * @return The projection-matrix that should be used to render. + */ + const Matrix& GetFinalProjectionMatrix( BufferIndex bufferIndex ) const; + + /** * Retrieve the projection-matrix property querying interface. * @pre The camera is on-stage. * @return The projection-matrix property querying interface. @@ -267,6 +279,7 @@ private: uint32_t mUpdateViewFlag; ///< This is non-zero if the view matrix requires an update uint32_t mUpdateProjectionFlag; ///< This is non-zero if the projection matrix requires an update + int mProjectionRotation; ///< The rotaion angle of the projection const Node* mNode; ///< The node this scene graph camera belongs to public: // PROPERTIES @@ -289,6 +302,7 @@ public: // PROPERTIES DoubleBuffered< FrustumPlanes > mFrustum; ///< Clipping frustum; double buffered for input handling DoubleBuffered< Matrix > mInverseViewProjection; ///< Inverted viewprojection; double buffered for input handling + DoubleBuffered< Matrix > mFinalProjection; ///< Final projection matrix; double buffered for input handling }; @@ -426,6 +440,17 @@ inline void SetInvertYAxisMessage( EventThreadServices& eventThreadServices, con new (slot) LocalType( &camera, &Camera::SetInvertYAxis, parameter ); } +inline void RotateProjectionMessage( EventThreadServices& eventThreadServices, const Camera& camera, int parameter ) +{ + typedef MessageValue1< Camera, int > LocalType; + + // Reserve some memory inside the message queue + unsigned int* 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( &camera, &Camera::RotateProjection, parameter ); +} + } // namespace SceneGraph } // namespace Internal -- 2.7.4