X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Frendering%2Fscene-graph-renderer.cpp;h=d1ca2e6f011ba83b24303046c26ea391bfc7d44d;hb=3e619233d3b176575e823c7499764b8dd041d08e;hp=4fdad9776b81e714c8d7b066dabb21ec987cc34c;hpb=4bd2fbea750e7dc85627868d8d276cc416b01b5a;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/rendering/scene-graph-renderer.cpp b/dali/internal/update/rendering/scene-graph-renderer.cpp index 4fdad97..d1ca2e6 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -21,17 +21,14 @@ #include #include #include -#include -#include -#include +#include #include -#include +#include #include -#include #include -#include #include #include +#include namespace // unnamed namespace @@ -41,6 +38,9 @@ const unsigned int UNIFORM_MAP_READY = 0; const unsigned int COPY_UNIFORM_MAP = 1; const unsigned int REGENERATE_UNIFORM_MAP = 2; +//Memory pool used to allocate new renderers. Memory used by this pool will be released when shutting down DALi +Dali::Internal::MemoryPoolObjectAllocator gRendererMemoryPool; + void AddMappings( Dali::Internal::SceneGraph::CollectedUniformMap& localMap, const Dali::Internal::SceneGraph::UniformMap& uniformMap ) { // Iterate thru uniformMap. @@ -83,9 +83,22 @@ void AddMappings( Dali::Internal::SceneGraph::CollectedUniformMap& localMap, con const Dali::Internal::SceneGraph::UniformPropertyMapping* map = (*iter); localMap.PushBack( map ); } - //@todo MESH_REWORK Use memcpy to copy ptrs from one array to the other } } + +// flags for resending data to renderer +enum Flags +{ + RESEND_DATA_PROVIDER = 1, + RESEND_GEOMETRY = 1 << 1, + RESEND_FACE_CULLING_MODE = 1 << 2, + RESEND_BLEND_COLOR = 1 << 3, + RESEND_BLEND_BIT_MASK = 1 << 4, + RESEND_PREMULTIPLIED_ALPHA = 1 << 5, + RESEND_INDEXED_DRAW_FIRST_ELEMENT = 1 << 6, + RESEND_INDEXED_DRAW_ELEMENTS_COUNT = 1 << 7, +}; + } namespace Dali @@ -95,22 +108,32 @@ namespace Internal namespace SceneGraph { +Renderer* Renderer::New() +{ + return new ( gRendererMemoryPool.AllocateRawThreadSafe() ) Renderer(); +} + Renderer::Renderer() -:mSceneController(0), - mRenderer(NULL), - mMaterial(NULL), - mGeometry(NULL), - mReferenceCount(0), - mRegenerateUniformMap(0), - mResendDataProviders(false), - mResendGeometry(false), - mHasUntrackedResources(false), - mFinishedResourceAcquisition(false), - mResourcesReady(false), - mDepthIndex(0) -{ - mUniformMapChanged[0]=false; - mUniformMapChanged[1]=false; +:mSceneController( 0 ), + mRenderer( NULL ), + mTextureSet( NULL ), + mGeometry( NULL ), + mShader( NULL ), + mBlendColor( NULL ), + mBlendBitmask( 0u ), + mFaceCullingMode( Dali::Renderer::NONE ), + mBlendingMode( Dali::BlendingMode::AUTO ), + mIndexedDrawFirstElement( 0 ), + mIndexedDrawElementsCount( 0 ), + mReferenceCount( 0 ), + mRegenerateUniformMap( 0 ), + mResendFlag( 0 ), + mResourcesReady( false ), + mFinishedResourceAcquisition( false ), + mDepthIndex( 0 ) +{ + mUniformMapChanged[0] = false; + mUniformMapChanged[1] = false; // Observe our own PropertyOwner's uniform map AddUniformMapObserver( *this ); @@ -118,26 +141,48 @@ Renderer::Renderer() Renderer::~Renderer() { - if (mMaterial) + if (mTextureSet) { - mMaterial->RemoveConnectionObserver(*this); - mMaterial=NULL; + mTextureSet->RemoveObserver(this); + mTextureSet=NULL; } - if (mGeometry) + if( mShader ) { - mGeometry->RemoveConnectionObserver(*this); - mGeometry=NULL; + mShader->RemoveConnectionObserver(*this); + mShader=NULL; } + } +void Renderer::operator delete( void* ptr ) +{ + gRendererMemoryPool.FreeThreadSafe( static_cast( ptr ) ); +} + + void Renderer::PrepareRender( BufferIndex updateBufferIndex ) { - mMaterial->PrepareRender( updateBufferIndex ); + mResourcesReady = false; + mFinishedResourceAcquisition = false; + + // Can only be considered ready when all the scene graph objects are connected to the renderer + if( mGeometry && mShader ) + { + if( mTextureSet ) + { + mTextureSet->GetResourcesStatus( mResourcesReady, mFinishedResourceAcquisition ); + } + else + { + mResourcesReady = true; + mFinishedResourceAcquisition = true; + } + } if( mRegenerateUniformMap > UNIFORM_MAP_READY ) { - DALI_ASSERT_DEBUG( mGeometry != NULL && "No geometry available in DoPrepareRender()" ); - DALI_ASSERT_DEBUG( mMaterial != NULL && "No geometry available in DoPrepareRender()" ); + DALI_ASSERT_DEBUG( mGeometry != NULL && "No geometry available in PrepareRender()" ); + DALI_ASSERT_DEBUG( mShader != NULL && "No shader available in PrepareRender()" ); if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP) { @@ -147,28 +192,9 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex ) const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap(); AddMappings( localMap, rendererUniformMap ); - AddMappings( localMap, mMaterial->GetUniformMap() ); - Vector& samplers = mMaterial->GetSamplers(); - unsigned int samplerCount( samplers.Size() ); - for( unsigned int i(0); iGetUniformMap() ); - } - - AddMappings( localMap, mMaterial->GetShader()->GetUniformMap() ); - AddMappings( localMap, mGeometry->GetUniformMap() ); - - Vector& vertexBuffers = mGeometry->GetVertexBuffers(); - unsigned int vertexBufferCount( vertexBuffers.Size() ); - for( unsigned int i(0); iGetUniformMap() ); - } - - PropertyBuffer* indexBuffer = mGeometry->GetIndexBuffer(); - if( indexBuffer ) - { - AddMappings( localMap, indexBuffer->GetUniformMap() ); + AddMappings( localMap, mShader->GetUniformMap() ); } } else if( mRegenerateUniformMap == COPY_UNIFORM_MAP ) @@ -190,59 +216,117 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex ) mRegenerateUniformMap--; } - if( mResendDataProviders ) + if( mResendFlag == 0 ) + { + return; + } + + if( mResendFlag & RESEND_DATA_PROVIDER ) { RenderDataProvider* dataProvider = NewRenderDataProvider(); - // Tell renderer about a new provider - // @todo MESH_REWORK Should we instead create a new renderer when these change? + typedef MessageValue1< Render::Renderer, OwnerPointer > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetRenderDataProvider, dataProvider ); + mResendFlag &= ~RESEND_DATA_PROVIDER; + } + + if( mResendFlag & RESEND_GEOMETRY ) + { + typedef MessageValue1< Render::Renderer, Render::Geometry* > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - typedef MessageValue1< Render::NewRenderer, OwnerPointer > DerivedType; + new (slot) DerivedType( mRenderer, &Render::Renderer::SetGeometry, mGeometry ); + mResendFlag &= ~RESEND_GEOMETRY; + } + + if( mResendFlag & RESEND_FACE_CULLING_MODE ) + { + typedef MessageValue1< Render::Renderer, Dali::Renderer::FaceCullingMode > DerivedType; unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::NewRenderer::SetRenderDataProvider, dataProvider ); - mResendDataProviders = false; + new (slot) DerivedType( mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode ); + mResendFlag &= ~RESEND_FACE_CULLING_MODE; } - if( mResendGeometry ) + if( mResendFlag & RESEND_BLEND_BIT_MASK ) { - // The first call to GetRenderGeometry() creates the geometry and sends it in a message - RenderGeometry* geometry = mGeometry->GetRenderGeometry( mSceneController ); + typedef MessageValue1< Render::Renderer, unsigned int > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask ); + mResendFlag &= ~RESEND_BLEND_BIT_MASK; + } - typedef MessageValue1< Render::NewRenderer, RenderGeometry* > DerivedType; + if( mResendFlag & RESEND_BLEND_COLOR ) + { + typedef MessageValue1< Render::Renderer, const Vector4* > DerivedType; unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendColor, mBlendColor ); + mResendFlag &= ~RESEND_BLEND_COLOR; + } - new (slot) DerivedType( mRenderer, &Render::NewRenderer::SetGeometry, geometry ); - mResendGeometry = false; + if( mResendFlag & RESEND_PREMULTIPLIED_ALPHA ) + { + typedef MessageValue1< Render::Renderer, bool > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled ); + mResendFlag &= ~RESEND_PREMULTIPLIED_ALPHA; + } + + if( mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT ) + { + typedef MessageValue1< Render::Renderer, size_t > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement ); + mResendFlag &= ~RESEND_INDEXED_DRAW_FIRST_ELEMENT; + } + + if( mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT ) + { + typedef MessageValue1< Render::Renderer, size_t > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount ); + mResendFlag &= ~RESEND_INDEXED_DRAW_FIRST_ELEMENT; } } -void Renderer::SetMaterial( BufferIndex bufferIndex, Material* material) +void Renderer::SetTextures( TextureSet* textureSet ) { - DALI_ASSERT_DEBUG( material != NULL && "Material pointer is NULL" ); + DALI_ASSERT_DEBUG( textureSet != NULL && "Texture set pointer is NULL" ); - mMaterial = material; - mMaterial->AddConnectionObserver( *this ); - mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; + if( mTextureSet ) + { + mTextureSet->RemoveObserver(this); + } - mResendDataProviders = true; + mTextureSet = textureSet; + mTextureSet->AddObserver( this ); + mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; + mResendFlag |= RESEND_DATA_PROVIDER; } -void Renderer::SetGeometry( BufferIndex bufferIndex, Geometry* geometry) +void Renderer::SetShader( Shader* shader ) { - DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL"); - if( mGeometry) + DALI_ASSERT_DEBUG( shader != NULL && "Shader pointer is NULL" ); + + if( mShader ) { - mGeometry->RemoveConnectionObserver(*this); - mGeometry->OnRendererDisconnect(); + mShader->RemoveConnectionObserver(*this); } - mGeometry = geometry; - mGeometry->AddConnectionObserver( *this ); // Observe geometry connections / uniform mapping changes + mShader = shader; + mShader->AddConnectionObserver( *this ); mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; + mResendFlag |= RESEND_DATA_PROVIDER; +} + +void Renderer::SetGeometry( Render::Geometry* geometry ) +{ + DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL"); + mGeometry = geometry; if( mRenderer ) { - mResendGeometry = true; + mResendFlag |= RESEND_GEOMETRY; } } @@ -251,6 +335,58 @@ void Renderer::SetDepthIndex( int depthIndex ) mDepthIndex = depthIndex; } +void Renderer::SetFaceCullingMode( unsigned int faceCullingMode ) +{ + mFaceCullingMode = static_cast(faceCullingMode); + mResendFlag |= RESEND_FACE_CULLING_MODE; +} + +void Renderer::SetBlendingMode( unsigned int blendingMode ) +{ + mBlendingMode = static_cast< BlendingMode::Type >( blendingMode ); +} + +void Renderer::SetBlendingOptions( unsigned int options ) +{ + if( mBlendBitmask != options) + { + mBlendBitmask = options; + mResendFlag |= RESEND_BLEND_BIT_MASK; + } +} + +void Renderer::SetBlendColor( const Vector4& blendColor ) +{ + if( !mBlendColor ) + { + mBlendColor = new Vector4( blendColor ); + } + else + { + *mBlendColor = blendColor; + } + + mResendFlag |= RESEND_BLEND_COLOR; +} + +void Renderer::SetIndexedDrawFirstElement( size_t firstElement ) +{ + mIndexedDrawFirstElement = firstElement; + mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT; +} + +void Renderer::SetIndexedDrawElementsCount( size_t elementsCount ) +{ + mIndexedDrawElementsCount = elementsCount; + mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT; +} + +void Renderer::EnablePreMultipliedAlpha( bool preMultipled ) +{ + mPremultipledAlphaEnabled = preMultipled; + mResendFlag |= RESEND_PREMULTIPLIED_ALPHA; +} + //Called when a node with this renderer is added to the stage void Renderer::OnStageConnect() { @@ -259,11 +395,12 @@ void Renderer::OnStageConnect() { RenderDataProvider* dataProvider = NewRenderDataProvider(); - RenderGeometry* renderGeometry = mGeometry->GetRenderGeometry(mSceneController); - mRenderer = Render::NewRenderer::New( dataProvider, renderGeometry ); + mRenderer = Render::Renderer::New( dataProvider, mGeometry, + mBlendBitmask, mBlendColor, + static_cast< Dali::Renderer::FaceCullingMode >( mFaceCullingMode ), + mPremultipledAlphaEnabled ); mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer ); - mResendDataProviders = false; - mResendGeometry = false; + mResendFlag = 0; } } @@ -302,16 +439,18 @@ RenderDataProvider* Renderer::NewRenderDataProvider() { RenderDataProvider* dataProvider = new RenderDataProvider(); - dataProvider->mMaterialDataProvider = mMaterial; dataProvider->mUniformMapDataProvider = this; - dataProvider->mShader = mMaterial->GetShader(); + dataProvider->mShader = mShader; - Vector& samplers = mMaterial->GetSamplers(); - unsigned int sampleCount( samplers.Count() ); - dataProvider->mSamplers.Resize( sampleCount ); - for( unsigned int i(0); imSamplers[i] = samplers[i]; // Convert from derived type to base type + size_t textureCount( mTextureSet->GetTextureCount() ); + dataProvider->mTextures.resize( textureCount ); + for( unsigned int i(0); imTextures[i] = Render::Texture( mTextureSet->GetTextureId(i), + mTextureSet->GetTextureSampler(i)); + } } return dataProvider; @@ -327,149 +466,59 @@ const CollectedUniformMap& Renderer::GetUniformMap( BufferIndex bufferIndex ) co return mCollectedUniformMap[bufferIndex]; }; -void Renderer::PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager ) +void Renderer::GetReadyAndComplete( bool& ready, bool& complete ) const { - mHasUntrackedResources = false; - mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea - - DALI_ASSERT_DEBUG( mSceneController ); - - CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager(); - mResourcesReady = false; - + ready = mResourcesReady; + complete = mFinishedResourceAcquisition; +} - mFinishedResourceAcquisition = false; +Renderer::Opacity Renderer::GetOpacity( BufferIndex updateBufferIndex, const Node& node ) const +{ + Renderer::Opacity opacity = Renderer::OPAQUE; - // Can only be considered ready when all the scene graph objects are connected to the renderer - if( ( mGeometry ) && ( mGeometry->GetVertexBuffers().Count() > 0 ) && - ( mMaterial ) && ( mMaterial->GetShader() != NULL ) ) + switch( mBlendingMode ) { - unsigned int completeCount = 0; - unsigned int neverCount = 0; - unsigned int frameBufferCount = 0; - - Vector& samplers = mMaterial->GetSamplers(); - unsigned int samplerCount( samplers.Size() ); - for( unsigned int i(0); iGetTextureId( updateBufferIndex ); - BitmapMetadata metaData = resourceManager.GetBitmapMetadata( textureId ); - - samplers[i]->SetFullyOpaque( metaData.IsFullyOpaque() ); - - switch( completeStatusManager.GetStatus( textureId ) ) + opacity = Renderer::TRANSLUCENT; + break; + } + case BlendingMode::AUTO: + { + bool shaderRequiresBlending( mShader->GeometryHintEnabled( Dali::ShaderEffect::HINT_BLENDING ) ); + if( shaderRequiresBlending || ( mTextureSet && mTextureSet->HasAlpha() ) ) { - case CompleteStatusManager::NOT_READY: - { - if( metaData.GetIsFramebuffer() ) - { - frameBufferCount++; - } - if( completeStatusManager.FindResourceTracker(textureId) != NULL ) - { - bool found = false; - std::size_t numTrackedResources = mTrackedResources.Count(); - for( size_t i=0; i < numTrackedResources; ++i ) - { - if(mTrackedResources[i] == textureId) - { - found = true; - break; - } - } - if( ! found ) - { - mTrackedResources.PushBack( textureId ); - } - } - else - { - mHasUntrackedResources = true; - } - } - break; - - case CompleteStatusManager::COMPLETE: + opacity = Renderer::TRANSLUCENT; + } + else // renderer should determine opacity using the actor color + { + float alpha = node.GetWorldColor( updateBufferIndex ).a; + if( alpha <= FULLY_TRANSPARENT ) { - completeCount++; + opacity = TRANSPARENT; } - break; - - case CompleteStatusManager::NEVER: + else if( alpha <= FULLY_OPAQUE ) { - neverCount++; + opacity = TRANSLUCENT; } - break; } + break; } - - // We are ready if all samplers are complete, or those that aren't are framebuffers - // We are complete if all samplers are either complete or will nmResendGeometryever complete - mResourcesReady = ( completeCount + frameBufferCount >= samplers.Count() ) ; - mFinishedResourceAcquisition = ( completeCount + neverCount >= samplers.Count() ); - } -} - -void Renderer::GetReadyAndComplete(bool& ready, bool& complete) const -{ - ready = mResourcesReady; - complete = false; - - CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager(); - - std::size_t numTrackedResources = mTrackedResources.Count(); - if( mHasUntrackedResources || numTrackedResources == 0 ) - { - complete = mFinishedResourceAcquisition; - } - else - { - // If there are tracked resources and no untracked resources, test the trackers - bool trackersComplete = true; - for( size_t i=0; i < numTrackedResources; ++i ) + case BlendingMode::OFF: // the renderer should never use blending + default: { - ResourceId id = mTrackedResources[i]; - ResourceTracker* tracker = completeStatusManager.FindResourceTracker(id); - if( tracker && ! tracker->IsComplete() ) - { - trackersComplete = false; - break; - } + opacity = Renderer::OPAQUE; + break; } - - complete = mFinishedResourceAcquisition || trackersComplete; } -} -// Called by ProcessRenderTasks after DoPrepareRender -bool Renderer::IsFullyOpaque( BufferIndex updateBufferIndex, const Node& node ) const -{ - bool opaque = false; - if( mMaterial != NULL ) - { - Material::BlendPolicy blendPolicy = mMaterial->GetBlendPolicy(); - switch( blendPolicy ) - { - case Material::OPAQUE: - { - opaque = true; - break; - } - case Material::TRANSPARENT: - { - opaque = false; - break; - } - case Material::USE_ACTOR_COLOR: - { - opaque = node.GetWorldColor( updateBufferIndex ).a >= FULLY_OPAQUE; - break; - } - } - } + return opacity; +} - return opaque; +void Renderer::TextureSetChanged() +{ + mResendFlag |= RESEND_DATA_PROVIDER; } void Renderer::ConnectionsChanged( PropertyOwner& object ) @@ -479,7 +528,7 @@ void Renderer::ConnectionsChanged( PropertyOwner& object ) mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; // Ensure the child object pointers get re-sent to the renderer - mResendDataProviders = true; + mResendFlag |= RESEND_DATA_PROVIDER; } void Renderer::ConnectedUniformMapChanged() @@ -495,13 +544,13 @@ void Renderer::UniformMappingsChanged( const UniformMap& mappings ) void Renderer::ObservedObjectDestroyed(PropertyOwner& owner) { - if( reinterpret_cast(mGeometry) == &owner ) + if( reinterpret_cast(mTextureSet) == &owner ) { - mGeometry = NULL; + mTextureSet = NULL; } - else if( reinterpret_cast(mMaterial) == &owner ) + else if( reinterpret_cast(mShader) == &owner ) { - mMaterial = NULL; + mShader = NULL; } }