X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Frendering%2Fscene-graph-renderer.cpp;h=f2ecb414a75b6de66a817d2a57680cd9d48fe4d4;hb=1c3a73918ec7054bac9caa5bdf3eebcecc54fd7a;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..f2ecb41 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -17,22 +17,18 @@ // CLASS HEADER #include "scene-graph-renderer.h" -// INTERNAL HEADERS -#include -#include +// INTERNAL INCLUDES +#include +#include #include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include +#include +#include #include -#include - +#include +#include +#include namespace // unnamed namespace { @@ -41,6 +37,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,10 +82,35 @@ 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 re-sending data to renderer. +enum Flags +{ + RESEND_DATA_PROVIDER = 1 << 0, + 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, + RESEND_DEPTH_WRITE_MODE = 1 << 8, + RESEND_DEPTH_TEST_MODE = 1 << 9, + RESEND_DEPTH_FUNCTION = 1 << 10, + RESEND_RENDER_MODE = 1 << 11, + RESEND_STENCIL_FUNCTION = 1 << 12, + RESEND_STENCIL_FUNCTION_MASK = 1 << 13, + RESEND_STENCIL_FUNCTION_REFERENCE = 1 << 14, + RESEND_STENCIL_MASK = 1 << 15, + RESEND_STENCIL_OPERATION_ON_FAIL = 1 << 16, + RESEND_STENCIL_OPERATION_ON_Z_FAIL = 1 << 17, + RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 18, + RESEND_WRITE_TO_COLOR_BUFFER = 1 << 19, +}; + +} // Anonymous namespace namespace Dali { @@ -95,22 +119,34 @@ 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 ), + mStencilParameters( RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ), + mIndexedDrawFirstElement( 0u ), + mIndexedDrawElementsCount( 0u ), + mBlendBitmask( 0u ), + mRegenerateUniformMap( 0u ), + mResendFlag( 0u ), + mDepthFunction( DepthFunction::LESS ), + mFaceCullingMode( FaceCullingMode::NONE ), + mBlendMode( BlendMode::AUTO ), + mDepthWriteMode( DepthWriteMode::AUTO ), + mDepthTestMode( DepthTestMode::AUTO ), + mPremultipledAlphaEnabled( false ), + mDepthIndex( 0 ) +{ + mUniformMapChanged[0] = false; + mUniformMapChanged[1] = false; // Observe our own PropertyOwner's uniform map AddUniformMapObserver( *this ); @@ -118,27 +154,32 @@ 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::PrepareRender( BufferIndex updateBufferIndex ) +void Renderer::operator delete( void* ptr ) { - mMaterial->PrepareRender( updateBufferIndex ); + gRendererMemoryPool.FreeThreadSafe( static_cast( ptr ) ); +} - 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()" ); +void Renderer::PrepareRender( BufferIndex updateBufferIndex ) +{ + if( mRegenerateUniformMap == UNIFORM_MAP_READY ) + { + mUniformMapChanged[updateBufferIndex] = false; + } + else + { if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP) { CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ]; @@ -147,28 +188,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 ) + if( mShader ) { - AddMappings( localMap, indexBuffer->GetUniformMap() ); + AddMappings( localMap, mShader->GetUniformMap() ); } } else if( mRegenerateUniformMap == COPY_UNIFORM_MAP ) @@ -190,59 +212,185 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex ) mRegenerateUniformMap--; } - if( mResendDataProviders ) + if( mResendFlag != 0 ) { - RenderDataProvider* dataProvider = NewRenderDataProvider(); + if( mResendFlag & RESEND_DATA_PROVIDER ) + { + OwnerPointer 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 ); + } - typedef MessageValue1< Render::NewRenderer, OwnerPointer > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::NewRenderer::SetRenderDataProvider, dataProvider ); - mResendDataProviders = false; - } + if( mResendFlag & RESEND_GEOMETRY ) + { + typedef MessageValue1< Render::Renderer, Render::Geometry* > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetGeometry, mGeometry ); + } - if( mResendGeometry ) - { - // The first call to GetRenderGeometry() creates the geometry and sends it in a message - RenderGeometry* geometry = mGeometry->GetRenderGeometry( mSceneController ); + if( mResendFlag & RESEND_FACE_CULLING_MODE ) + { + typedef MessageValue1< Render::Renderer, FaceCullingMode::Type > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode ); + } + + if( mResendFlag & RESEND_BLEND_BIT_MASK ) + { + typedef MessageValue1< Render::Renderer, unsigned int > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask ); + } + + if( mResendFlag & RESEND_BLEND_COLOR ) + { + typedef MessageValue1< Render::Renderer, Vector4 > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendColor, GetBlendColor() ); + } + + 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 ); + } + + 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 ); + } + + 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 ); + } + + if( mResendFlag & RESEND_DEPTH_WRITE_MODE ) + { + typedef MessageValue1< Render::Renderer, DepthWriteMode::Type > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode ); + } + + if( mResendFlag & RESEND_DEPTH_TEST_MODE ) + { + typedef MessageValue1< Render::Renderer, DepthTestMode::Type > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthTestMode, mDepthTestMode ); + } + + if( mResendFlag & RESEND_DEPTH_FUNCTION ) + { + typedef MessageValue1< Render::Renderer, DepthFunction::Type > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction ); + } - typedef MessageValue1< Render::NewRenderer, RenderGeometry* > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + if( mResendFlag & RESEND_RENDER_MODE ) + { + typedef MessageValue1< Render::Renderer, RenderMode::Type > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetRenderMode, mStencilParameters.renderMode ); + } + + if( mResendFlag & RESEND_STENCIL_FUNCTION ) + { + typedef MessageValue1< Render::Renderer, StencilFunction::Type > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilFunction, mStencilParameters.stencilFunction ); + } + + if( mResendFlag & RESEND_STENCIL_FUNCTION_MASK ) + { + typedef MessageValue1< Render::Renderer, int > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilFunctionMask, mStencilParameters.stencilFunctionMask ); + } + + if( mResendFlag & RESEND_STENCIL_FUNCTION_REFERENCE ) + { + typedef MessageValue1< Render::Renderer, int > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilFunctionReference, mStencilParameters.stencilFunctionReference ); + } + + if( mResendFlag & RESEND_STENCIL_MASK ) + { + typedef MessageValue1< Render::Renderer, int > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilMask, mStencilParameters.stencilMask ); + } - new (slot) DerivedType( mRenderer, &Render::NewRenderer::SetGeometry, geometry ); - mResendGeometry = false; + if( mResendFlag & RESEND_STENCIL_OPERATION_ON_FAIL ) + { + typedef MessageValue1< Render::Renderer, StencilOperation::Type > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilOperationOnFail, mStencilParameters.stencilOperationOnFail ); + } + + if( mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_FAIL ) + { + typedef MessageValue1< Render::Renderer, StencilOperation::Type > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilOperationOnZFail, mStencilParameters.stencilOperationOnZFail ); + } + + if( mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_PASS ) + { + typedef MessageValue1< Render::Renderer, StencilOperation::Type > DerivedType; + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass ); + } + + mResendFlag = 0; } } -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,31 +399,129 @@ void Renderer::SetDepthIndex( int depthIndex ) mDepthIndex = depthIndex; } -//Called when a node with this renderer is added to the stage -void Renderer::OnStageConnect() +void Renderer::SetFaceCullingMode( FaceCullingMode::Type faceCullingMode ) { - ++mReferenceCount; - if( !mRenderer) - { - RenderDataProvider* dataProvider = NewRenderDataProvider(); + mFaceCullingMode = faceCullingMode; + mResendFlag |= RESEND_FACE_CULLING_MODE; +} + +void Renderer::SetBlendMode( BlendMode::Type blendingMode ) +{ + mBlendMode = blendingMode; +} - RenderGeometry* renderGeometry = mGeometry->GetRenderGeometry(mSceneController); - mRenderer = Render::NewRenderer::New( dataProvider, renderGeometry ); - mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer ); - mResendDataProviders = false; - mResendGeometry = false; +void Renderer::SetBlendingOptions( unsigned int options ) +{ + if( mBlendBitmask != options) + { + mBlendBitmask = options; + mResendFlag |= RESEND_BLEND_BIT_MASK; } } -//Called when the node with this renderer has gone out of the stage -void Renderer::OnStageDisconnect() +void Renderer::SetBlendColor( const Vector4& blendColor ) { - --mReferenceCount; - if( mReferenceCount == 0 ) + if( blendColor == Color::TRANSPARENT ) { - mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer ); - mRenderer = NULL; + mBlendColor = NULL; + } + else + { + 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; +} + +void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode ) +{ + mDepthWriteMode = depthWriteMode; + mResendFlag |= RESEND_DEPTH_WRITE_MODE; +} + +void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode ) +{ + mDepthTestMode = depthTestMode; + mResendFlag |= RESEND_DEPTH_TEST_MODE; +} + +void Renderer::SetDepthFunction( DepthFunction::Type depthFunction ) +{ + mDepthFunction = depthFunction; + mResendFlag |= RESEND_DEPTH_FUNCTION; +} + +void Renderer::SetRenderMode( RenderMode::Type mode ) +{ + mStencilParameters.renderMode = mode; + mResendFlag |= RESEND_RENDER_MODE; +} + +void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction ) +{ + mStencilParameters.stencilFunction = stencilFunction; + mResendFlag |= RESEND_STENCIL_FUNCTION; +} + +void Renderer::SetStencilFunctionMask( int stencilFunctionMask ) +{ + mStencilParameters.stencilFunctionMask = stencilFunctionMask; + mResendFlag |= RESEND_STENCIL_FUNCTION_MASK; +} + +void Renderer::SetStencilFunctionReference( int stencilFunctionReference ) +{ + mStencilParameters.stencilFunctionReference = stencilFunctionReference; + mResendFlag |= RESEND_STENCIL_FUNCTION_REFERENCE; +} + +void Renderer::SetStencilMask( int stencilMask ) +{ + mStencilParameters.stencilMask = stencilMask; + mResendFlag |= RESEND_STENCIL_MASK; +} + +void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail ) +{ + mStencilParameters.stencilOperationOnFail = stencilOperationOnFail; + mResendFlag |= RESEND_STENCIL_OPERATION_ON_FAIL; +} + +void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail ) +{ + mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail; + mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_FAIL; +} + +void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass ) +{ + mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass; + mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS; } //Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created ) @@ -283,8 +529,14 @@ void Renderer::ConnectToSceneGraph( SceneController& sceneController, BufferInde { mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; mSceneController = &sceneController; -} + RenderDataProvider* dataProvider = NewRenderDataProvider(); + + mRenderer = Render::Renderer::New( dataProvider, mGeometry, mBlendBitmask, GetBlendColor(), static_cast< FaceCullingMode::Type >( mFaceCullingMode ), + mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters ); + OwnerPointer< Render::Renderer > transferOwnership( mRenderer ); + mSceneController->GetRenderMessageDispatcher().AddRenderer( transferOwnership ); +} //Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced ) void Renderer::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex ) @@ -294,29 +546,41 @@ void Renderer::DisconnectFromSceneGraph( SceneController& sceneController, Buffe { mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer ); mRenderer = NULL; - mSceneController = NULL; } + mSceneController = NULL; } 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 ); + dataProvider->mSamplers.resize( textureCount ); + for( unsigned int i(0); imTextures[i] = mTextureSet->GetTexture(i); + dataProvider->mSamplers[i] = mTextureSet->GetTextureSampler(i); + } } return dataProvider; } +const Vector4& Renderer::GetBlendColor() const +{ + if( mBlendColor ) + { + return *mBlendColor; + } + return Color::TRANSPARENT; +} + Render::Renderer& Renderer::GetRenderer() { return *mRenderer; @@ -325,153 +589,62 @@ Render::Renderer& Renderer::GetRenderer() const CollectedUniformMap& Renderer::GetUniformMap( BufferIndex bufferIndex ) const { return mCollectedUniformMap[bufferIndex]; -}; +} -void Renderer::PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager ) +Renderer::Opacity Renderer::GetOpacity( BufferIndex updateBufferIndex, const Node& node ) const { - mHasUntrackedResources = false; - mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea - - DALI_ASSERT_DEBUG( mSceneController ); - - CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager(); - mResourcesReady = false; - - - mFinishedResourceAcquisition = false; + 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( mBlendMode ) { - 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 BlendMode::AUTO: + { + bool shaderRequiresBlending( mShader->HintEnabled( Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT ) ); + 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 BlendMode::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; } + + return opacity; } -// Called by ProcessRenderTasks after DoPrepareRender -bool Renderer::IsFullyOpaque( BufferIndex updateBufferIndex, const Node& node ) const +void Renderer::TextureSetChanged() { - bool opaque = false; + mResendFlag |= RESEND_DATA_PROVIDER; +} - 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; - } - } - } +void Renderer::TextureSetDeleted() +{ + mTextureSet = NULL; - return opaque; + mResendFlag |= RESEND_DATA_PROVIDER; } - void Renderer::ConnectionsChanged( PropertyOwner& object ) { // One of our child objects has changed it's connections. Ensure the uniform @@ -479,7 +652,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 +668,9 @@ void Renderer::UniformMappingsChanged( const UniformMap& mappings ) void Renderer::ObservedObjectDestroyed(PropertyOwner& owner) { - if( reinterpret_cast(mGeometry) == &owner ) - { - mGeometry = NULL; - } - else if( reinterpret_cast(mMaterial) == &owner ) + if( reinterpret_cast(mShader) == &owner ) { - mMaterial = NULL; + mShader = NULL; } }