From 2faaf2d19385cb18dbac0288be2f49ec8b78bb84 Mon Sep 17 00:00:00 2001 From: Tom Robinson Date: Mon, 3 Oct 2016 12:28:21 +0100 Subject: [PATCH] VR: Core object impl. Encapsuales render-manager VR code. Replaces constraint + animation to set eye pose Change-Id: Ie72942cd569d3ede528753081db5ba28e26785ba --- dali/integration-api/vr-engine.h | 15 +- dali/internal/common/core-impl.cpp | 12 +- dali/internal/common/core-impl.h | 4 +- dali/internal/common/vr-manager-impl.cpp | 175 +++++++++++++++++++++++ dali/internal/common/vr-manager-impl.h | 84 +++++++++++ dali/internal/event/actors/camera-actor-impl.cpp | 5 + dali/internal/event/actors/camera-actor-impl.h | 6 + dali/internal/event/common/stage-impl.cpp | 69 ++------- dali/internal/event/common/stage-impl.h | 28 ---- dali/internal/file.list | 1 + dali/internal/render/common/render-manager.cpp | 114 +++------------ dali/internal/render/common/render-manager.h | 18 +-- dali/internal/update/manager/update-manager.cpp | 19 ++- dali/internal/update/manager/update-manager.h | 22 ++- dali/internal/update/nodes/node.h | 12 ++ 15 files changed, 376 insertions(+), 208 deletions(-) create mode 100644 dali/internal/common/vr-manager-impl.cpp create mode 100644 dali/internal/common/vr-manager-impl.h diff --git a/dali/integration-api/vr-engine.h b/dali/integration-api/vr-engine.h index 92453fd..df436a6 100644 --- a/dali/integration-api/vr-engine.h +++ b/dali/integration-api/vr-engine.h @@ -40,10 +40,10 @@ struct VrEngineRenderTargetInfo int colorTextures[2]; // if -1, then engine will create those buffers int depthTextures[2]; }; -} +} // Anonymous namespace + /** * @brief The VrEngine class - * */ class VrEngine { @@ -61,7 +61,7 @@ public: EYE_BUFFER_COUNT, // int, number of buffers ( 1 buffer for both eyes ), rw // render target by data structure - EYE_RENDER_TARGETS, // [VrEngineRenderTargetInfo*] + EYE_RENDER_TARGETS, // [VrEngineRenderTargetInfo*] EYE_BUFFER_WIDTH, // [int] width of single eye renderable area EYE_BUFFER_HEIGHT, // [int] height of single eye renderable area @@ -80,7 +80,7 @@ public: EYE_LEFT_TEXTURE3_ID = EYE_LEFT_TEXTURE_ID+3, EYE_RIGHT_CURRENT_TEXTURE_ID, // [int] ro, texture id to be written to ( updated with frame index ) - EYE_RIGHT_TEXTURE_ID = 1065, // [int] rw, right eye texture id for buffer ( must be passed as EYE_RIGHT_TEXTURE_ID+N ) + EYE_RIGHT_TEXTURE_ID = 1065, // [int] rw, right eye texture id for buffer ( must be passed as EYE_RIGHT_TEXTURE_ID+N ) // helper enums EYE_RIGHT_TEXTURE0_ID = EYE_RIGHT_TEXTURE_ID, EYE_RIGHT_TEXTURE1_ID = EYE_RIGHT_TEXTURE_ID+1, @@ -96,7 +96,9 @@ public: EYE_RIGHT_DEPTH_TEXTURE_ID = 3064,// [int] right eye depth texture for buffer (EYE_RIGHT_FBO_ID+N) }; - VrEngine() {} + VrEngine() + { + } virtual ~VrEngine() {} virtual bool Initialize( Vr::VrEngineInitParams* initParams ) = 0; @@ -140,6 +142,9 @@ public: } return true; } + +private: + }; } // Integration diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index 462196c..61fab05 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -28,7 +28,7 @@ #include // TODOVR -#include +//#include #include #include @@ -125,8 +125,9 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor(); - mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, *mGeometryBatcher, *mTextureUploadedQueue ); - mRenderManager->SetVrEngine( vrEngine ); + mVrManager = new VrManager( vrEngine ); + + mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, *mGeometryBatcher, *mVrManager, *mTextureUploadedQueue ); RenderQueue& renderQueue = mRenderManager->GetRenderQueue(); TextureCache& textureCache = mRenderManager->GetTextureCache(); @@ -159,7 +160,8 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, renderQueue, *mTextureCacheDispatcher, *mGeometryBatcher, - *mRenderTaskProcessor ); + *mRenderTaskProcessor, + *mVrManager ); mRenderManager->SetShaderSaver( *mUpdateManager ); @@ -169,7 +171,7 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) ); mStage->Initialize(); - mStage->SetVrEngine( vrEngine ); + mResourceClient = new ResourceClient( *mResourceManager, *mStage ); mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController); diff --git a/dali/internal/common/core-impl.h b/dali/internal/common/core-impl.h index f46f33e..88f63ff 100644 --- a/dali/internal/common/core-impl.h +++ b/dali/internal/common/core-impl.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,7 @@ public: Integration::GlSyncAbstraction& glSyncAbstraction, Integration::GestureManager& gestureManager, ResourcePolicy::DataRetention dataRetentionPolicy, - Integration::VrEngine* vrEngine); + Integration::VrEngine* vrEngine ); /** * Destructor @@ -300,6 +301,7 @@ private: IntrusivePtr< RelayoutController > mRelayoutController; ///< Size negotiation relayout controller SceneGraph::GeometryBatcher* mGeometryBatcher; ///< Instance of the geometry batcher SceneGraph::RenderTaskProcessor* mRenderTaskProcessor; ///< Handles the processing of render tasks + VrManager* mVrManager; ///< Provides functionality related to Tizen VR bool mIsActive : 1; ///< Whether Core is active or suspended bool mProcessingEvent : 1; ///< True during ProcessEvents() diff --git a/dali/internal/common/vr-manager-impl.cpp b/dali/internal/common/vr-manager-impl.cpp new file mode 100644 index 0000000..f3c398f --- /dev/null +++ b/dali/internal/common/vr-manager-impl.cpp @@ -0,0 +1,175 @@ +/* + * 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. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace +{ +#define GL(x) { x; int err = context.GetError(); if(err) { DALI_LOG_ERROR( "GL_ERROR: [%d] '%s', %x\n", __LINE__, #x, (unsigned)err);fflush(stderr);fflush(stdout);} else { /*DALI_LOG_ERROR("GL Call: %s\n", #x); fflush(stdout);*/} } +} // Anonymous namespace + + +VrManager::VrManager( Dali::Integration::VrEngine* vrEngine ) +: mVrEngine( vrEngine ), + mHeadNode( NULL ), + mEnabled( true ), + mEngineInitialized( false ) +{ +} + +VrManager::~VrManager() +{ +} + +void VrManager::SetEnabled( bool enabled ) +{ + mEnabled = enabled; +} + +bool VrManager::IsEnabled() const +{ + return mEnabled; +} + +void VrManager::SetHeadNode( SceneGraph::Node* node ) +{ + if( node ) + { + mHeadNode = node; + } +} + +void VrManager::UpdateHeadOrientation() +{ + // We need VR to be enabled and this manager to be initialized to update the head. + if( mEnabled && mVrEngine && mHeadNode ) + { + Dali::Integration::Vr::VrEngineEyePose eyePose; + + if( mVrEngine->Get( Dali::Integration::VrEngine::EYE_CURRENT_POSE, &eyePose ) ) + { + std::cout << "todor: VRMANAGER: UpdateHeadOrientation: Setting orientation: " << eyePose.rotation << std::endl; + mHeadNode->SetOrientation( eyePose.rotation ); + } + else + { + std::cout << "todor: VRMANAGER: UpdateHeadOrientation: Setting orientation: DEFAULT" << std::endl; + mHeadNode->SetOrientation( Quaternion( 1.0f, 0.0f, 0.0f, 0.0f ) ); + } + } +} + +void VrManager::PrepareRender( int surfaceWidth, int surfaceHeight ) +{ + // If VR is enabled and ready to setup (yet not yet initialized), initialize the engine now. + if( mEnabled && mVrEngine ) + { + if( !mEngineInitialized ) + { + // Initialise VR engine. + Dali::Integration::Vr::VrEngineInitParams params; + memset( ¶ms, 0, sizeof( Dali::Integration::Vr::VrEngineInitParams ) ); + params.screenWidth = surfaceWidth; + params.screenHeight = surfaceHeight; + + mVrEngine->Initialize( ¶ms ); + mEngineInitialized = true; + + // Start VR engine. + mVrEngine->Start(); + } + + // Perform the Pre-Render. + mVrEngine->PreRender(); + } +} + +bool VrManager::RenderEyes( Context& context, Dali::Camera::Type cameraType ) +{ + bool vrEye = false; + + if( mEnabled && mVrEngine ) + { + context.GetError(); + + // This reads all the required VR information in one go. + int leftFrameBufferObject(-1); + int rightFrameBufferObject(-1); + int leftTexture(-1); + int rightTexture(-1); + int bufferWidth(-1); + int bufferHeight(-1); + + static const int properties[] = + { + Dali::Integration::VrEngine::EYE_LEFT_CURRENT_FBO_ID, Dali::Integration::VrEngine::EYE_RIGHT_CURRENT_FBO_ID, + Dali::Integration::VrEngine::EYE_LEFT_CURRENT_TEXTURE_ID, Dali::Integration::VrEngine::EYE_RIGHT_CURRENT_TEXTURE_ID, + Dali::Integration::VrEngine::EYE_BUFFER_WIDTH, Dali::Integration::VrEngine::EYE_BUFFER_HEIGHT + }; + + void* values[] = + { + &leftFrameBufferObject, &rightFrameBufferObject, &leftTexture, &rightTexture, &bufferWidth, &bufferHeight + }; + + if( cameraType == Dali::Camera::VR_EYE_LEFT ) + { + vrEye = true; + mVrEngine->Get( properties, values, 6 ); + + GL( context.BindFramebuffer( GL_FRAMEBUFFER, leftFrameBufferObject ) ); + GL( context.Bind2dTexture( leftTexture ) ); + GL( context.TexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ) ); + } + else if( cameraType == Dali::Camera::VR_EYE_RIGHT ) + { + vrEye = true; + mVrEngine->Get( properties, values, 6 ); + + GL( context.BindFramebuffer( GL_FRAMEBUFFER, rightFrameBufferObject) ); + GL( context.Bind2dTexture( rightTexture ) ); + GL( context.TexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ) ); + } + } + + return vrEye; +} + +void VrManager::SubmitFrame( Context& context ) +{ + if( mEnabled && mVrEngine ) + { + context.Flush(); + mVrEngine->SubmitFrame(); + } +} + + +} // Internal + +} // Dali diff --git a/dali/internal/common/vr-manager-impl.h b/dali/internal/common/vr-manager-impl.h new file mode 100644 index 0000000..7193552 --- /dev/null +++ b/dali/internal/common/vr-manager-impl.h @@ -0,0 +1,84 @@ +#ifndef DALI_VR_MANAGER_H +#define DALI_VR_MANAGER_H + +//todor +#include +#include +#include +#include + +namespace Dali +{ + +namespace Internal +{ + + +/** + * Object managing access to VR abstraction. + */ +class VrManager +{ + public: + + /** + * @brief todor + */ + VrManager( Dali::Integration::VrEngine* vrEngine ); + /** + * @brief todor + */ + ~VrManager(); + + /** + * @brief todor + */ + void SetEnabled( bool enabled ); + + /** + * @brief todor + */ + bool IsEnabled() const; + + /** + * @brief todor + */ + void SetHeadNode( SceneGraph::Node* node ); + + /** + * @brief todor + */ + void UpdateHeadOrientation(); + + /** + * @brief todor + */ + void PrepareRender( int surfaceWidth, int surfaceHeight ); + + /** + * @brief todor + */ + bool RenderEyes( Context& context, Dali::Camera::Type cameraType ); + + /** + * @brief todor + */ + void SubmitFrame( Context& context ); + + private: + + Dali::Integration::VrEngine* mVrEngine; ///< todor + SceneGraph::Node* mHeadNode; + bool mEnabled; + bool mEngineInitialized; + +}; + + +} // Internal + +} // Dali + +#endif // DALI_VR_MANAGER_H + + diff --git a/dali/internal/event/actors/camera-actor-impl.cpp b/dali/internal/event/actors/camera-actor-impl.cpp index 60def88..0d687aa 100644 --- a/dali/internal/event/actors/camera-actor-impl.cpp +++ b/dali/internal/event/actors/camera-actor-impl.cpp @@ -535,6 +535,11 @@ const SceneGraph::Camera* CameraActor::GetCamera() const return mSceneObject; } +SceneGraph::Node& CameraActor::GetCameraNode() +{ + return *( (SceneGraph::Node*)mNode ); +} + unsigned int CameraActor::GetDefaultPropertyCount() const { return Actor::GetDefaultPropertyCount() + DEFAULT_PROPERTY_COUNT; diff --git a/dali/internal/event/actors/camera-actor-impl.h b/dali/internal/event/actors/camera-actor-impl.h index 7ae5053..fb0b8c0 100644 --- a/dali/internal/event/actors/camera-actor-impl.h +++ b/dali/internal/event/actors/camera-actor-impl.h @@ -215,6 +215,12 @@ public: */ const SceneGraph::Camera* GetCamera() const; + /** + * Return the scene graph camera node. + * @return The camera node + */ + SceneGraph::Node& GetCameraNode(); + public: // properties /** diff --git a/dali/internal/event/common/stage-impl.cpp b/dali/internal/event/common/stage-impl.cpp index 27a7241..3cb5078 100644 --- a/dali/internal/event/common/stage-impl.cpp +++ b/dali/internal/event/common/stage-impl.cpp @@ -39,12 +39,13 @@ #include #include #include -#include //TODOVR +//TODOVR +#include #include +#include using Dali::Internal::SceneGraph::Node; -using Dali::Integration::VrEngine; using namespace Dali::Integration::Vr; namespace Dali @@ -63,42 +64,8 @@ enum Eye RIGHT }; -//TODOVR: Sensor constraints -struct VrEyeConstraint -{ - VrEyeConstraint( Dali::Internal::Stage* stage ) - : stage( stage ) - { - } - - void operator()( Quaternion& current, const PropertyInputContainer& inputs ) - { - // TODO: get gyro data, update rotation - // get data from sensor - Dali::Integration::VrEngine* vrEngine( stage->GetVrEngine() ); - if( !vrEngine ) - { - return; - } - - VrEngineEyePose eyePose; - eyePose.rotation = current; - if( vrEngine->Get( VrEngine::EYE_CURRENT_POSE, &eyePose ) ) - { - current = eyePose.rotation; - } - else - { - current = Quaternion( 1.0f, 0.0f, 0.0f, 0.0f ); - } - } - - Dali::Internal::Stage* stage; -}; - //TODOVR const float DEFAULT_STEREO_BASE( 10.0f ); -//const float DEFAULT_STEREO_BASE( 15.0f ); // Signals @@ -351,6 +318,7 @@ SystemOverlay* Stage::GetSystemOverlayInternal() void Stage::UpdateCameras() { + std::cout << "todor: Stage::UpdateCameras(): mViewMode: " << mViewMode << std::endl; switch( mViewMode ) { case MONO: @@ -429,7 +397,6 @@ void Stage::UpdateCameras() } else { - #if 0 // Portrait aspect - default to VR on device. // Precalculations: @@ -468,9 +435,8 @@ void Stage::UpdateCameras() float fov = std::atan( viewPortHeight / ( 2.0f * mSize.width ) ); const float far = 300.0f; float IPD = 0.0635f; - stereoBase = -IPD*0.5f; - const float near = IPD+0.1f; - //stereoBase = 0.0f; + stereoBase = -IPD * 0.5f; + const float near = IPD + 0.1f; fov = Radian( Degree(106) ); mStereoInfo[L].camera->SetPerspectiveProjectionFovY( fov, cameraAspect, near, far, Vector2( +stereoBase, 0.0f ) ); @@ -491,23 +457,15 @@ void Stage::UpdateCameras() } - mVRGyroEyeConstraint = Constraint::New( mDefaultCamera.Get(), - Dali::Actor::Property::ORIENTATION, - VrEyeConstraint( this )); - mVRGyroEyeConstraint.Apply(); - Dali::Actor actor( mDefaultCamera.Get() ); - Quaternion quaternion( Radian(Degree(0)), Vector3( 0.0f, 0.0f, 0.0f )); - mVRDefaultCameraAnimation = Dali::Animation::New( 1.0f ); - mVRDefaultCameraAnimation.AnimateBy( Property( actor, Dali::Actor::Property::ORIENTATION ), quaternion, AlphaFunction::LINEAR ); - mVRDefaultCameraAnimation.SetLooping( true ); - mVRDefaultCameraAnimation.Play(); - mStereoInfo[L].camera->SetType( Camera::VR_EYE_LEFT ); mStereoInfo[R].camera->SetType( Camera::VR_EYE_RIGHT ); // Same settings regardless of orientation: - //stereoBase = 0; mStereoInfo[L].camera->SetPosition( Vector3( 0.0f, -stereoBase, 0.0f ) ); - mStereoInfo[R].camera->SetPosition( Vector3( 0.f, +stereoBase, 0.0f ) ); + mStereoInfo[R].camera->SetPosition( Vector3( 0.0f, +stereoBase, 0.0f ) ); + + // Inform the VR manager of the Vr head node. + Dali::Internal::SceneGraph::SetVrHeadNode( GetUpdateManager(), mDefaultCamera->GetCameraNode() ); + break; } @@ -558,19 +516,14 @@ void Stage::SetViewMode( ViewMode viewMode ) //TODOVR: Animate the look angle for testing. #if 0 Quaternion q = mDefaultCamera->GetCurrentOrientation(); - float duration = 3.0f; mCamAnim = Dali::Animation::New( duration ); - Dali::CameraActor a = Dali::CameraActor( ( mDefaultCamera.Get() ) ); - float lookAngle = 20.0f; mDefaultCamera->SetOrientation( Degree( ( 180.0f - ( lookAngle / 2.0f ) ) ), Vector3::YAXIS ); - mCamAnim.AnimateBy( Dali::Property( a, Dali::Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( lookAngle ) ), Vector3::YAXIS ), AlphaFunction::EASE_IN_OUT, TimePeriod( 0.0f, duration / 2.0f ) ); mCamAnim.AnimateBy( Dali::Property( a, Dali::Actor::Property::ORIENTATION ), Quaternion( Radian( Degree( -lookAngle ) ), Vector3::YAXIS ), AlphaFunction::EASE_IN_OUT, TimePeriod( duration / 2.0f, duration / 2.0f ) ); mCamAnim.SetLooping( true ); - mDefaultCamera->SetOrientation( Radian( Math::PI * 0.95f ), Vector3::YAXIS ); #endif } diff --git a/dali/internal/event/common/stage-impl.h b/dali/internal/event/common/stage-impl.h index 9658d0d..2daad0b 100644 --- a/dali/internal/event/common/stage-impl.h +++ b/dali/internal/event/common/stage-impl.h @@ -45,7 +45,6 @@ struct Vector2; namespace Integration { class SystemOverlay; -class VrEngine; } namespace Internal @@ -64,17 +63,6 @@ class SystemOverlay; class CameraActor; class RenderTaskList; -#if 0 -namespace -{ -struct StereoInfo -{ - Dali::RenderTask renderTask; - IntrusivePtr camera; -}; -} -#endif - /** * Implementation of Stage */ @@ -427,20 +415,6 @@ public: // Implementation of EventThreadServices */ virtual BufferIndex GetEventBufferIndex() const; -public: - - // VR - void SetVrEngine( Dali::Integration::VrEngine* vrEngine ) - { - mVrEngine = vrEngine; - } - - Dali::Integration::VrEngine* GetVrEngine() - { - return mVrEngine; - } - - private: /** @@ -498,8 +472,6 @@ private: // The list of render-tasks IntrusivePtr mRenderTaskList; - Dali::Integration::VrEngine* mVrEngine; - //TODOVR struct StereoInfo { diff --git a/dali/internal/file.list b/dali/internal/file.list index a4d1c9d..3ce4c24 100644 --- a/dali/internal/file.list +++ b/dali/internal/file.list @@ -10,6 +10,7 @@ internal_src_files = \ $(internal_src_dir)/common/image-sampler.cpp \ $(internal_src_dir)/common/image-attributes.cpp \ $(internal_src_dir)/common/fixed-size-memory-pool.cpp \ + $(internal_src_dir)/common/vr-manager-impl.cpp \ \ $(internal_src_dir)/event/actors/actor-impl.cpp \ $(internal_src_dir)/event/actors/custom-actor-internal.cpp \ diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 626c1f8..1c21ebd 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -43,7 +43,6 @@ //TODOVR #include -#include #include #include @@ -87,23 +86,6 @@ typedef RenderTrackerContainer::ConstIterator RenderTrackerConstIter; #define GL(x) { x; int err = mImpl->context.GetError(); if(err) { DALI_LOG_ERROR( "GL_ERROR: [%d] '%s', %x\n", __LINE__, #x, (unsigned)err);fflush(stderr);fflush(stdout);} else { /*DALI_LOG_ERROR("GL Call: %s\n", #x); fflush(stdout);*/} } /** - * Structure to contain VR rendering data - */ -struct VrImpl -{ - VrImpl() - : vrEngine( NULL ), - vrModeEnabled( true ), - initialised( false )//TODOVR - { - } - - Dali::Integration::VrEngine* vrEngine; - bool vrModeEnabled; - bool initialised; -}; - -/** * Structure to contain internal data */ struct RenderManager::Impl @@ -112,7 +94,8 @@ struct RenderManager::Impl Integration::GlSyncAbstraction& glSyncAbstraction, LockedResourceQueue& textureUploadedQ, TextureUploadedDispatcher& postProcessDispatcher, - GeometryBatcher& geometryBatcher ) + GeometryBatcher& geometryBatcher, + VrManager& vrManager ) : context( glAbstraction ), glSyncAbstraction( glSyncAbstraction ), renderQueue(), @@ -131,7 +114,8 @@ struct RenderManager::Impl firstRenderCompleted( false ), defaultShader( NULL ), programController( glAbstraction ), - geometryBatcher( geometryBatcher ) + geometryBatcher( geometryBatcher ), + vrManager( vrManager ) { } @@ -202,16 +186,17 @@ struct RenderManager::Impl SceneGraph::GeometryBatcher& geometryBatcher; ///< Instance of geometry batcher - VrImpl vrImpl; + Dali::Internal::VrManager& vrManager; ///< Provides functionality related to Tizen VR }; RenderManager* RenderManager::New( Integration::GlAbstraction& glAbstraction, Integration::GlSyncAbstraction& glSyncAbstraction, SceneGraph::GeometryBatcher& geometryBatcher, + VrManager& vrManager, LockedResourceQueue& textureUploadedQ ) { RenderManager* manager = new RenderManager; - manager->mImpl = new Impl( glAbstraction, glSyncAbstraction, textureUploadedQ, *manager, geometryBatcher ); + manager->mImpl = new Impl( glAbstraction, glSyncAbstraction, textureUploadedQ, *manager, geometryBatcher, vrManager ); return manager; } @@ -557,37 +542,14 @@ bool RenderManager::Render( Integration::RenderStatus& status ) // Process messages queued during previous update mImpl->renderQueue.ProcessMessages( mImpl->renderBufferIndex ); - VrImpl& vr = mImpl->vrImpl; - // No need to make any gl calls if we've done 1st glClear & don't have any renderers to render during startup. if( !mImpl->firstRenderCompleted || mImpl->renderersAdded ) { - // check if vr, if true create new main framebuffer, it's not the - // right place to do it, but will do for now - if( mImpl->vrImpl.vrModeEnabled/* && !mImpl->vrImpl.vrEngine*/ ) - { - if( mImpl->vrImpl.vrEngine && !mImpl->vrImpl.initialised ) - { - // initialise VR engine - VrEngineInitParams params; - memset( ¶ms, 0, sizeof( VrEngineInitParams ) ); - params.screenWidth = mImpl->defaultSurfaceRect.width; - params.screenHeight = mImpl->defaultSurfaceRect.height; - mImpl->vrImpl.vrEngine->Initialize( ¶ms ); - mImpl->vrImpl.initialised = true; - - // start VR engine - mImpl->vrImpl.vrEngine->Start(); - } - } - - // prerender - if( mImpl->vrImpl.vrModeEnabled && mImpl->vrImpl.vrEngine ) - { - mImpl->vrImpl.vrEngine->PreRender(); - } + // This will perform pre-render steps with the Tizen VR Engine IF using Tizen VR. + VrManager& vrManager = mImpl->vrManager; + vrManager.PrepareRender( mImpl->defaultSurfaceRect.width, mImpl->defaultSurfaceRect.height ); - if( !mImpl->vrImpl.vrModeEnabled ) + if( !vrManager.IsEnabled() ) { // switch rendering to adaptor provided (default) buffer GL( mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, 0 ) ); @@ -636,14 +598,8 @@ bool RenderManager::Render( Integration::RenderStatus& status ) mImpl->firstRenderCompleted = true; } - if( vr.vrModeEnabled ) - { - if( mImpl->vrImpl.vrEngine ) - { - mImpl->context.Flush(); - vr.vrEngine->SubmitFrame(); - } - } + // This will Submit frame to the Tizen VR Engine IF using Tizen VR. + vrManager.SubmitFrame( mImpl->context ); } //Notify RenderGeometries that rendering has finished @@ -723,41 +679,10 @@ void RenderManager::DoRender( RenderInstruction& instruction, Shader& defaultSha } else // !(instruction.mOffscreenTexture) { - VrEngine* vr = mImpl->vrImpl.vrEngine; - if( vr ) + if( mImpl->vrManager.IsEnabled() ) { - mImpl->context.GetError(); - - // will read all vr properties at once - int lfbo(-1), rfbo(-1), ltex(-1), rtex(-1), bufwidth(-1), bufheight(-1); - int properties[] = - { - VrEngine::EYE_LEFT_CURRENT_FBO_ID, VrEngine::EYE_RIGHT_CURRENT_FBO_ID, - VrEngine::EYE_LEFT_CURRENT_TEXTURE_ID, VrEngine::EYE_RIGHT_CURRENT_TEXTURE_ID, - VrEngine::EYE_BUFFER_WIDTH, VrEngine::EYE_BUFFER_HEIGHT - }; - void* values[] = - { - &lfbo, &rfbo, <ex, &rtex, &bufwidth, &bufheight - }; - if( instruction.mCamera->mType == Dali::Camera::VR_EYE_LEFT ) - { - vrEye = true; - vr->Get( properties, values, 6 ); - //DALI_LOG_ERROR("This is Left VR camera!\n"); - GL( mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, lfbo ) ); - GL( mImpl->context.Bind2dTexture( ltex ) ); - GL( mImpl->context.TexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, bufwidth, bufheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ) ); - } - else if( instruction.mCamera->mType == Dali::Camera::VR_EYE_RIGHT ) - { - vrEye = true; - vr->Get( properties, values, 6 ); - //DALI_LOG_ERROR("This is Right VR camera!\n"); - GL( mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, rfbo) ); - GL( mImpl->context.Bind2dTexture( rtex ) ); - GL( mImpl->context.TexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, bufwidth, bufheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL ) ); - } + // This will render the two eye textures IF using Tizen VR. + vrEye = mImpl->vrManager.RenderEyes( mImpl->context, instruction.mCamera->mType ); } else { @@ -779,8 +704,6 @@ void RenderManager::DoRender( RenderInstruction& instruction, Shader& defaultSha { viewportRect = mImpl->defaultSurfaceRect; } - - } mImpl->context.Viewport(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height); @@ -830,11 +753,6 @@ void RenderManager::DoRender( RenderInstruction& instruction, Shader& defaultSha } } -void RenderManager::SetVrEngine( Integration::VrEngine* vrEngine ) -{ - mImpl->vrImpl.vrEngine = vrEngine; -} - } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/render/common/render-manager.h b/dali/internal/render/common/render-manager.h index fe02664..175e59a 100644 --- a/dali/internal/render/common/render-manager.h +++ b/dali/internal/render/common/render-manager.h @@ -1,8 +1,8 @@ -#ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDER_MANAGER_H__ -#define __DALI_INTERNAL_SCENE_GRAPH_RENDER_MANAGER_H__ +#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_MANAGER_H +#define DALI_INTERNAL_SCENE_GRAPH_RENDER_MANAGER_H /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * 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. @@ -21,6 +21,7 @@ // INTERNAL INCLUDES #include #include +#include #include #include #include @@ -79,13 +80,16 @@ public: * @param[in] glAbstraction The GL abstraction used for rendering. * @param[in] glSyncAbstraction The GL sync abstraction used fence sync creation/deletion. * @param[in] geometryBatcher The geometry batcher instance - * @param[out] resourcePostProcessQueue A queue for sending rendered texture ids to the update-thread.* + * @param[in] vrManager Provides access to the core VR module + * @param[out] resourcePostProcessQueue A queue for sending rendered texture ids to the update-thread. */ static RenderManager* New( Integration::GlAbstraction& glAbstraction, Integration::GlSyncAbstraction& glSyncAbstraction, SceneGraph::GeometryBatcher& geometryBatcher, + VrManager& vrManager, LockedResourceQueue& resourcePostProcessQueue ); + /** * Non-virtual destructor; not intended as a base class */ @@ -360,10 +364,6 @@ private: */ void DoRender( RenderInstruction& instruction, Shader& defaultShader ); -public: - - void SetVrEngine( Dali::Integration::VrEngine* vrEngine ); - private: /** @@ -390,4 +390,4 @@ private: } // namespace Dali -#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_MANAGER_H__ +#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_MANAGER_H diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 08e12c4..0c54666 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -134,7 +134,8 @@ struct UpdateManager::Impl RenderQueue& renderQueue, SceneGraphBuffers& sceneGraphBuffers, GeometryBatcher& geometryBatcher, - RenderTaskProcessor& renderTaskProcessor ) + RenderTaskProcessor& renderTaskProcessor, + VrManager& vrManager ) : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ), notificationManager( notificationManager ), transformManager(), @@ -150,6 +151,7 @@ struct UpdateManager::Impl renderInstructions( renderManager.GetRenderInstructionContainer() ), geometryBatcher( geometryBatcher ), renderTaskProcessor( renderTaskProcessor ), + vrManager( vrManager ), backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ), taskList( renderMessageDispatcher, resourceManager ), systemLevelTaskList( renderMessageDispatcher, resourceManager ), @@ -235,6 +237,7 @@ struct UpdateManager::Impl RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions GeometryBatcher& geometryBatcher; ///< An instance of the GeometryBatcher RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons + VrManager& vrManager; ///< Provides functionality related to Tizen VR Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame. @@ -287,7 +290,8 @@ UpdateManager::UpdateManager( NotificationManager& notificationManager, RenderQueue& renderQueue, TextureCacheDispatcher& textureCacheDispatcher, GeometryBatcher& geometryBatcher, - RenderTaskProcessor& renderTaskProcessor ) + RenderTaskProcessor& renderTaskProcessor, + VrManager& vrManager ) : mImpl(NULL) { mImpl = new Impl( notificationManager, @@ -300,7 +304,8 @@ UpdateManager::UpdateManager( NotificationManager& notificationManager, renderQueue, mSceneGraphBuffers, geometryBatcher, - renderTaskProcessor ); + renderTaskProcessor, + vrManager ); textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers ); mImpl->geometryBatcher.SetUpdateManager( this ); @@ -351,6 +356,11 @@ void UpdateManager::AddNode( Node* node ) } } +void UpdateManager::SetVrHeadNode( Node* node ) +{ + mImpl->vrManager.SetHeadNode( node ); +} + void UpdateManager::ConnectNode( Node* parent, Node* node ) { DALI_ASSERT_ALWAYS( NULL != parent ); @@ -950,6 +960,9 @@ unsigned int UpdateManager::Update( float elapsedSeconds, //Forward compiled shader programs to event thread for saving ForwardCompiledShadersToEventThread(); + // Update the camera look direction from the VR eye pose. + mImpl->vrManager.UpdateHeadOrientation(); + // Although the scene-graph may not require an update, we still need to synchronize double-buffered // renderer lists if the scene was updated in the previous frame. // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 6d2406a..660bce0 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -56,6 +56,7 @@ class NotificationManager; class CompleteNotificationInterface; class ResourceManager; class TouchResampler; +class VrManager; namespace Render { @@ -106,6 +107,7 @@ public: * @param[in] textureCacheDispatcher Used for sending messages to texture cache. * @param[in] geometryBatcher Used when geometry batching is enabled. * @param[in] renderTaskProcessor Handles RenderTasks and RenderInstrucitons. + * @param[in] vrManager Provides access to Tizen VR */ UpdateManager( NotificationManager& notificationManager, CompleteNotificationInterface& animationFinishedNotifier, @@ -117,7 +119,8 @@ public: RenderQueue& renderQueue, TextureCacheDispatcher& textureCacheDispatcher, GeometryBatcher& geometryBatcher, - RenderTaskProcessor& renderTaskProcessor ); + RenderTaskProcessor& renderTaskProcessor, + VrManager& vrManager ); /** * Destructor. @@ -152,6 +155,12 @@ public: void AddNode( Node* node ); /** + * @brief Sets the node to represent the VR "head". + * @param[in] node The node to use + */ + void SetVrHeadNode( Node* node ); + + /** * Connect a Node to the scene-graph. * A disconnected Node has has no parent or children, and its properties cannot be animated/constrained. * @pre The node does not already have a parent. @@ -1282,6 +1291,17 @@ inline void AttachColorTextureToFrameBuffer( UpdateManager& manager, Render::Fra new (slot) LocalType( &manager, &UpdateManager::AttachColorTextureToFrameBuffer, &frameBuffer, texture, mipmapLevel, layer ); } +inline void SetVrHeadNode( UpdateManager& manager, Node& node ) +{ + typedef MessageValue1< UpdateManager, OwnerPointer > 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::SetVrHeadNode, &node ); +} + } // namespace SceneGraph diff --git a/dali/internal/update/nodes/node.h b/dali/internal/update/nodes/node.h index 3cd0117..7b50ebb 100644 --- a/dali/internal/update/nodes/node.h +++ b/dali/internal/update/nodes/node.h @@ -412,6 +412,18 @@ public: } /** + * Set the local orientation of the node, relative to its parent. + * @param[in] orientation The orientation to set. + */ + void SetOrientation( const Quaternion& orientation ) + { + if( mTransformId != INVALID_TRANSFORM_ID ) + { + mOrientation.Set( 0, orientation ); + } + } + + /** * Retrieve the local orientation of the node, relative to its parent. * @param[in] bufferIndex The buffer to read from. * @return The local orientation. -- 2.7.4