X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Frendering%2Fscene-graph-renderer.cpp;h=9e982a812de5d9272df815f08dd7a9091e296741;hb=9d8818db1ee5ad9497cb7698be2a4752f6ecf50e;hp=715a83f61282c41d5613611f25fa917f1e863922;hpb=e2ee93d144c63abb914c086281d09c40b213919f;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 715a83f..9e982a8 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) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -18,69 +18,77 @@ #include "scene-graph-renderer.h" // INTERNAL INCLUDES +#include #include #include -#include -#include -#include -#include #include +#include #include #include #include -#include +#include +#include +#include +#include +#include +namespace Dali +{ +namespace Internal +{ +namespace SceneGraph +{ namespace // unnamed namespace { - -const unsigned int UNIFORM_MAP_READY = 0; -const unsigned int COPY_UNIFORM_MAP = 1; -const unsigned int REGENERATE_UNIFORM_MAP = 2; +const uint32_t UNIFORM_MAP_READY = 0; +const uint32_t COPY_UNIFORM_MAP = 1; +const uint32_t 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; +MemoryPoolObjectAllocator gRendererMemoryPool; -void AddMappings( Dali::Internal::SceneGraph::CollectedUniformMap& localMap, const Dali::Internal::SceneGraph::UniformMap& uniformMap ) +void AddMappings(CollectedUniformMap& localMap, const UniformMap& uniformMap) { // Iterate thru uniformMap. - // Any maps that aren't in localMap should be added in a single step - Dali::Internal::SceneGraph::CollectedUniformMap newUniformMappings; + // Any maps that aren't in localMap should be added in a single step + + // keep a static vector to avoid temporary heap allocation. + // As this function gets called only from update thread we don't have to + // make it thread safe (so no need to keep a thread_local variable). + static CollectedUniformMap newUniformMappings; + + newUniformMappings.Clear(); - for( unsigned int i=0, count=uniformMap.Count(); iuniformNameHash == nameHash ) + const UniformPropertyMapping& map = (*iter); + if(map.uniformName == uniformMap[i].uniformName) { - if( map->uniformName == uniformMap[i].uniformName ) - { - found = true; - break; - } + found = true; + break; } } - if( !found ) + if(!found) { - // it's a new mapping. Add raw ptr to temporary list - newUniformMappings.PushBack( &uniformMap[i] ); + newUniformMappings.PushBack(uniformMap[i]); } } - if( newUniformMappings.Count() > 0 ) + if(newUniformMappings.Count() > 0) { - localMap.Reserve( localMap.Count() + newUniformMappings.Count() ); + localMap.Reserve(localMap.Count() + newUniformMappings.Count()); - for( Dali::Internal::SceneGraph::CollectedUniformMap::Iterator iter = newUniformMappings.Begin(), - end = newUniformMappings.End() ; - iter != end ; - ++iter ) + for(CollectedUniformMap::Iterator iter = newUniformMappings.Begin(), + end = newUniformMappings.End(); + iter != end; + ++iter) { - const Dali::Internal::SceneGraph::UniformPropertyMapping* map = (*iter); - localMap.PushBack( map ); + const UniformPropertyMapping& map = (*iter); + localMap.PushBack(map); } } } @@ -88,117 +96,125 @@ void AddMappings( Dali::Internal::SceneGraph::CollectedUniformMap& localMap, con // 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, + RESEND_GEOMETRY = 1 << 0, + RESEND_FACE_CULLING_MODE = 1 << 1, + RESEND_BLEND_COLOR = 1 << 2, + RESEND_BLEND_BIT_MASK = 1 << 3, + RESEND_PREMULTIPLIED_ALPHA = 1 << 4, + RESEND_INDEXED_DRAW_FIRST_ELEMENT = 1 << 5, + RESEND_INDEXED_DRAW_ELEMENTS_COUNT = 1 << 6, + RESEND_DEPTH_WRITE_MODE = 1 << 7, + RESEND_DEPTH_TEST_MODE = 1 << 8, + RESEND_DEPTH_FUNCTION = 1 << 9, + RESEND_RENDER_MODE = 1 << 10, + RESEND_STENCIL_FUNCTION = 1 << 11, + RESEND_STENCIL_FUNCTION_MASK = 1 << 12, + RESEND_STENCIL_FUNCTION_REFERENCE = 1 << 13, + RESEND_STENCIL_MASK = 1 << 14, + RESEND_STENCIL_OPERATION_ON_FAIL = 1 << 15, + RESEND_STENCIL_OPERATION_ON_Z_FAIL = 1 << 16, + RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 17, + RESEND_WRITE_TO_COLOR_BUFFER = 1 << 18, + RESEND_SHADER = 1 << 19, + RESEND_DRAW_COMMANDS = 1 << 20, + RESEND_SET_RENDER_CALLBACK = 1 << 21 }; } // Anonymous namespace -namespace Dali -{ -namespace Internal -{ -namespace SceneGraph -{ - Renderer* Renderer::New() { - return new ( gRendererMemoryPool.AllocateRawThreadSafe() ) Renderer(); + return new(gRendererMemoryPool.AllocateRawThreadSafe()) Renderer(); } Renderer::Renderer() -: 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 ) +: mSceneController(nullptr), + mRenderer(nullptr), + mTextureSet(nullptr), + mGeometry(nullptr), + mShader(nullptr), + mBlendColor(nullptr), + 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), + mRenderingBehavior(DevelRenderer::Rendering::IF_REQUIRED), + mPremultipledAlphaEnabled(false), + mOpacity(1.0f), + mDepthIndex(0) { mUniformMapChanged[0] = false; mUniformMapChanged[1] = false; // Observe our own PropertyOwner's uniform map - AddUniformMapObserver( *this ); + AddUniformMapObserver(*this); } Renderer::~Renderer() { - if( mTextureSet ) + if(mTextureSet) { - mTextureSet->RemoveObserver( this ); - mTextureSet = NULL; + mTextureSet = nullptr; } - if( mShader ) + if(mShader) { - mShader->RemoveConnectionObserver( *this ); - mShader = NULL; + mShader->RemoveConnectionObserver(*this); + mShader = nullptr; } } -void Renderer::operator delete( void* ptr ) +void Renderer::operator delete(void* ptr) { - gRendererMemoryPool.FreeThreadSafe( static_cast( ptr ) ); + gRendererMemoryPool.FreeThreadSafe(static_cast(ptr)); } - -void Renderer::PrepareRender( BufferIndex updateBufferIndex ) +bool Renderer::PrepareRender(BufferIndex updateBufferIndex) { - if( mRegenerateUniformMap > UNIFORM_MAP_READY ) + if(mRegenerateUniformMap == UNIFORM_MAP_READY) { - if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP) + mUniformMapChanged[updateBufferIndex] = false; + } + else + { + if(mRegenerateUniformMap == REGENERATE_UNIFORM_MAP) { - CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ]; - localMap.Resize(0); + CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex]; + localMap.Clear(); const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap(); - AddMappings( localMap, rendererUniformMap ); - if( mShader ) + auto size = rendererUniformMap.Count(); + if(mShader) + { + size += mShader->GetUniformMap().Count(); + } + + localMap.Reserve(size); + + AddMappings(localMap, rendererUniformMap); + + if(mShader) { - AddMappings( localMap, mShader->GetUniformMap() ); + AddMappings(localMap, mShader->GetUniformMap()); } } - else if( mRegenerateUniformMap == COPY_UNIFORM_MAP ) + else if(mRegenerateUniformMap == COPY_UNIFORM_MAP) { // Copy old map into current map - CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ]; - CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-updateBufferIndex ]; + CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex]; + CollectedUniformMap& oldMap = mCollectedUniformMap[1 - updateBufferIndex]; - localMap.Resize( oldMap.Count() ); + localMap.Resize(oldMap.Count()); - unsigned int index=0; - for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index ) + uint32_t index = 0; + for(CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End(); iter != end; ++iter, ++index) { localMap[index] = *iter; } @@ -208,224 +224,258 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex ) mRegenerateUniformMap--; } - if( mResendFlag != 0 ) + bool rendererUpdated = mUniformMapChanged[updateBufferIndex] || mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY; + + if(mResendFlag != 0) { - if( mResendFlag & RESEND_DATA_PROVIDER ) + if(mResendFlag & RESEND_GEOMETRY) { - OwnerPointer dataProvider = NewRenderDataProvider(); + typedef MessageValue1 DerivedType; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetGeometry, mGeometry); + } - typedef MessageValue1< Render::Renderer, OwnerPointer > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetRenderDataProvider, dataProvider ); + if(mResendFlag & RESEND_DRAW_COMMANDS) + { + using DerivedType = MessageValue2; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetDrawCommands, mDrawCommands.data(), mDrawCommands.size()); } - if( mResendFlag & RESEND_GEOMETRY ) + if(mResendFlag & RESEND_FACE_CULLING_MODE) { - typedef MessageValue1< Render::Renderer, Render::Geometry* > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetGeometry, mGeometry ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode); } - if( mResendFlag & RESEND_FACE_CULLING_MODE ) + if(mResendFlag & RESEND_BLEND_BIT_MASK) { - typedef MessageValue1< Render::Renderer, FaceCullingMode::Type > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask); } - if( mResendFlag & RESEND_BLEND_BIT_MASK ) + if(mResendFlag & RESEND_BLEND_COLOR) { - typedef MessageValue1< Render::Renderer, unsigned int > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendColor, GetBlendColor()); } - if( mResendFlag & RESEND_BLEND_COLOR ) + if(mResendFlag & RESEND_PREMULTIPLIED_ALPHA) { - typedef MessageValue1< Render::Renderer, Vector4 > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendColor, GetBlendColor() ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled); } - if( mResendFlag & RESEND_PREMULTIPLIED_ALPHA ) + if(mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT) { - typedef MessageValue1< Render::Renderer, bool > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement); } - if( 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::SetIndexedDrawFirstElement, mIndexedDrawFirstElement ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount); } - if( mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT ) + if(mResendFlag & RESEND_DEPTH_WRITE_MODE) { - typedef MessageValue1< Render::Renderer, size_t > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode); } - if( mResendFlag & RESEND_DEPTH_WRITE_MODE ) + if(mResendFlag & RESEND_DEPTH_TEST_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 ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthTestMode, mDepthTestMode); } - if( mResendFlag & RESEND_DEPTH_TEST_MODE ) + if(mResendFlag & RESEND_DEPTH_FUNCTION) { - typedef MessageValue1< Render::Renderer, DepthTestMode::Type > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthTestMode, mDepthTestMode ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction); } - if( mResendFlag & RESEND_DEPTH_FUNCTION ) + if(mResendFlag & RESEND_RENDER_MODE) { - typedef MessageValue1< Render::Renderer, DepthFunction::Type > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderMode, mStencilParameters.renderMode); } - if( mResendFlag & RESEND_RENDER_MODE ) + if(mResendFlag & RESEND_STENCIL_FUNCTION) { - 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 ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunction, mStencilParameters.stencilFunction); } - if( mResendFlag & RESEND_STENCIL_FUNCTION ) + if(mResendFlag & RESEND_STENCIL_FUNCTION_MASK) { - 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 ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionMask, mStencilParameters.stencilFunctionMask); } - if( mResendFlag & RESEND_STENCIL_FUNCTION_MASK ) + 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::SetStencilFunctionMask, mStencilParameters.stencilFunctionMask ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionReference, mStencilParameters.stencilFunctionReference); } - if( mResendFlag & RESEND_STENCIL_FUNCTION_REFERENCE ) + 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::SetStencilFunctionReference, mStencilParameters.stencilFunctionReference ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilMask, mStencilParameters.stencilMask); } - if( mResendFlag & RESEND_STENCIL_MASK ) + if(mResendFlag & RESEND_STENCIL_OPERATION_ON_FAIL) { - typedef MessageValue1< Render::Renderer, int > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilMask, mStencilParameters.stencilMask ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnFail, mStencilParameters.stencilOperationOnFail); } - if( mResendFlag & RESEND_STENCIL_OPERATION_ON_FAIL ) + 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::SetStencilOperationOnFail, mStencilParameters.stencilOperationOnFail ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZFail, mStencilParameters.stencilOperationOnZFail); } - if( mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_FAIL ) + 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::SetStencilOperationOnZFail, mStencilParameters.stencilOperationOnZFail ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass); } - if( mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_PASS ) + if(mResendFlag & RESEND_SHADER) { - 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 ); + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetShaderChanged, true); + } + + if(mResendFlag & RESEND_SET_RENDER_CALLBACK) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderCallback, mRenderCallback); } mResendFlag = 0; } + + return rendererUpdated; } -void Renderer::SetTextures( TextureSet* textureSet ) +void Renderer::SetTextures(TextureSet* textureSet) { - DALI_ASSERT_DEBUG( textureSet != NULL && "Texture set pointer is NULL" ); + DALI_ASSERT_DEBUG(textureSet != NULL && "Texture set pointer is NULL"); - if( mTextureSet ) - { - mTextureSet->RemoveObserver(this); - } - - mTextureSet = textureSet; - mTextureSet->AddObserver( this ); + mTextureSet = textureSet; mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; - mResendFlag |= RESEND_DATA_PROVIDER; } -void Renderer::SetShader( Shader* shader ) +const Vector* Renderer::GetTextures() const +{ + return mTextureSet ? &(mTextureSet->GetTextures()) : nullptr; +} + +const Vector* Renderer::GetSamplers() const { - DALI_ASSERT_DEBUG( shader != NULL && "Shader pointer is NULL" ); + return mTextureSet ? &(mTextureSet->GetSamplers()) : nullptr; +} + +void Renderer::SetShader(Shader* shader) +{ + DALI_ASSERT_DEBUG(shader != NULL && "Shader pointer is NULL"); - if( mShader ) + if(mShader) { mShader->RemoveConnectionObserver(*this); } mShader = shader; - mShader->AddConnectionObserver( *this ); + mShader->AddConnectionObserver(*this); mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; - mResendFlag |= RESEND_DATA_PROVIDER; + mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER; } -void Renderer::SetGeometry( Render::Geometry* geometry ) +void Renderer::SetGeometry(Render::Geometry* geometry) { - DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL"); + DALI_ASSERT_DEBUG(geometry != NULL && "Geometry pointer is NULL"); mGeometry = geometry; - if( mRenderer ) + if(mRenderer) { mResendFlag |= RESEND_GEOMETRY; } } -void Renderer::SetDepthIndex( int depthIndex ) +void Renderer::SetDepthIndex(int depthIndex) { mDepthIndex = depthIndex; } -void Renderer::SetFaceCullingMode( FaceCullingMode::Type faceCullingMode ) +void Renderer::SetFaceCullingMode(FaceCullingMode::Type faceCullingMode) { mFaceCullingMode = faceCullingMode; mResendFlag |= RESEND_FACE_CULLING_MODE; } -void Renderer::SetBlendMode( BlendMode::Type blendingMode ) +FaceCullingMode::Type Renderer::GetFaceCullingMode() const +{ + return mFaceCullingMode; +} + +void Renderer::SetBlendMode(BlendMode::Type blendingMode) { mBlendMode = blendingMode; } -void Renderer::SetBlendingOptions( unsigned int options ) +BlendMode::Type Renderer::GetBlendMode() const +{ + return mBlendMode; +} + +void Renderer::SetBlendingOptions(uint32_t options) { - if( mBlendBitmask != options) + if(mBlendBitmask != options) { mBlendBitmask = options; mResendFlag |= RESEND_BLEND_BIT_MASK; } } -void Renderer::SetBlendColor( const Vector4& blendColor ) +uint32_t Renderer::GetBlendingOptions() const { - if( blendColor == Color::TRANSPARENT ) + return mBlendBitmask; +} + +void Renderer::SetBlendColor(const Vector4& blendColor) +{ + if(blendColor == Color::TRANSPARENT) { - mBlendColor = NULL; + mBlendColor = nullptr; } else { - if( !mBlendColor ) + if(!mBlendColor) { - mBlendColor = new Vector4( blendColor ); + mBlendColor = new Vector4(blendColor); } else { @@ -436,145 +486,182 @@ void Renderer::SetBlendColor( const Vector4& blendColor ) mResendFlag |= RESEND_BLEND_COLOR; } -void Renderer::SetIndexedDrawFirstElement( size_t firstElement ) +Vector4 Renderer::GetBlendColor() const +{ + if(mBlendColor) + { + return *mBlendColor; + } + return Color::TRANSPARENT; +} + +void Renderer::SetIndexedDrawFirstElement(uint32_t firstElement) { mIndexedDrawFirstElement = firstElement; mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT; } -void Renderer::SetIndexedDrawElementsCount( size_t elementsCount ) +uint32_t Renderer::GetIndexedDrawFirstElement() const +{ + return mIndexedDrawFirstElement; +} + +void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount) { mIndexedDrawElementsCount = elementsCount; mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT; } -void Renderer::EnablePreMultipliedAlpha( bool preMultipled ) +uint32_t Renderer::GetIndexedDrawElementsCount() const +{ + return mIndexedDrawElementsCount; +} + +void Renderer::EnablePreMultipliedAlpha(bool preMultipled) { mPremultipledAlphaEnabled = preMultipled; mResendFlag |= RESEND_PREMULTIPLIED_ALPHA; } -void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode ) +bool Renderer::IsPreMultipliedAlphaEnabled() const +{ + return mPremultipledAlphaEnabled; +} + +void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode) { mDepthWriteMode = depthWriteMode; mResendFlag |= RESEND_DEPTH_WRITE_MODE; } -void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode ) +DepthWriteMode::Type Renderer::GetDepthWriteMode() const +{ + return mDepthWriteMode; +} + +void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode) { mDepthTestMode = depthTestMode; mResendFlag |= RESEND_DEPTH_TEST_MODE; } -void Renderer::SetDepthFunction( DepthFunction::Type depthFunction ) +DepthTestMode::Type Renderer::GetDepthTestMode() const +{ + return mDepthTestMode; +} + +void Renderer::SetDepthFunction(DepthFunction::Type depthFunction) { mDepthFunction = depthFunction; mResendFlag |= RESEND_DEPTH_FUNCTION; } -void Renderer::SetRenderMode( RenderMode::Type mode ) +DepthFunction::Type Renderer::GetDepthFunction() const +{ + return mDepthFunction; +} + +void Renderer::SetRenderMode(RenderMode::Type mode) { mStencilParameters.renderMode = mode; mResendFlag |= RESEND_RENDER_MODE; } -void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction ) +void Renderer::SetStencilFunction(StencilFunction::Type stencilFunction) { mStencilParameters.stencilFunction = stencilFunction; mResendFlag |= RESEND_STENCIL_FUNCTION; } -void Renderer::SetStencilFunctionMask( int stencilFunctionMask ) +void Renderer::SetStencilFunctionMask(int stencilFunctionMask) { mStencilParameters.stencilFunctionMask = stencilFunctionMask; mResendFlag |= RESEND_STENCIL_FUNCTION_MASK; } -void Renderer::SetStencilFunctionReference( int stencilFunctionReference ) +void Renderer::SetStencilFunctionReference(int stencilFunctionReference) { mStencilParameters.stencilFunctionReference = stencilFunctionReference; mResendFlag |= RESEND_STENCIL_FUNCTION_REFERENCE; } -void Renderer::SetStencilMask( int stencilMask ) +void Renderer::SetStencilMask(int stencilMask) { mStencilParameters.stencilMask = stencilMask; mResendFlag |= RESEND_STENCIL_MASK; } -void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail ) +void Renderer::SetStencilOperationOnFail(StencilOperation::Type stencilOperationOnFail) { mStencilParameters.stencilOperationOnFail = stencilOperationOnFail; mResendFlag |= RESEND_STENCIL_OPERATION_ON_FAIL; } -void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail ) +void Renderer::SetStencilOperationOnZFail(StencilOperation::Type stencilOperationOnZFail) { mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail; mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_FAIL; } -void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass ) +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 ) -void Renderer::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex ) +void Renderer::SetRenderCallback(RenderCallback* callback) { - mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; - mSceneController = &sceneController; - RenderDataProvider* dataProvider = NewRenderDataProvider(); + mRenderCallback = callback; + mResendFlag |= RESEND_SET_RENDER_CALLBACK; +} - mRenderer = Render::Renderer::New( dataProvider, mGeometry, mBlendBitmask, GetBlendColor(), static_cast< FaceCullingMode::Type >( mFaceCullingMode ), - mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters ); +const Render::Renderer::StencilParameters& Renderer::GetStencilParameters() const +{ + return mStencilParameters; +} - OwnerPointer< Render::Renderer > transferOwnership( mRenderer ); - mSceneController->GetRenderMessageDispatcher().AddRenderer( transferOwnership ); +void Renderer::BakeOpacity(BufferIndex updateBufferIndex, float opacity) +{ + mOpacity.Bake(updateBufferIndex, opacity); } -//Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced ) -void Renderer::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex ) +float Renderer::GetOpacity(BufferIndex updateBufferIndex) const { - //Remove renderer from RenderManager - if( mRenderer ) - { - mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer ); - mRenderer = NULL; - } - mSceneController = NULL; + return mOpacity[updateBufferIndex]; } -RenderDataProvider* Renderer::NewRenderDataProvider() +void Renderer::SetRenderingBehavior(DevelRenderer::Rendering::Type renderingBehavior) { - RenderDataProvider* dataProvider = new RenderDataProvider(); + mRenderingBehavior = renderingBehavior; +} - dataProvider->mUniformMapDataProvider = this; - dataProvider->mShader = mShader; +DevelRenderer::Rendering::Type Renderer::GetRenderingBehavior() const +{ + return mRenderingBehavior; +} - if( mTextureSet ) - { - 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); - } - } +//Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created ) +void Renderer::ConnectToSceneGraph(SceneController& sceneController, BufferIndex bufferIndex) +{ + mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; + mSceneController = &sceneController; + + mRenderer = Render::Renderer::New(this, mGeometry, mBlendBitmask, GetBlendColor(), static_cast(mFaceCullingMode), mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters); - return dataProvider; + OwnerPointer transferOwnership(mRenderer); + mSceneController->GetRenderMessageDispatcher().AddRenderer(transferOwnership); } -const Vector4& Renderer::GetBlendColor() const +//Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced ) +void Renderer::DisconnectFromSceneGraph(SceneController& sceneController, BufferIndex bufferIndex) { - if( mBlendColor ) + //Remove renderer from RenderManager + if(mRenderer) { - return *mBlendColor; + mSceneController->GetRenderMessageDispatcher().RemoveRenderer(*mRenderer); + mRenderer = nullptr; } - return Color::TRANSPARENT; + mSceneController = nullptr; } Render::Renderer& Renderer::GetRenderer() @@ -582,73 +669,83 @@ Render::Renderer& Renderer::GetRenderer() return *mRenderer; } -const CollectedUniformMap& Renderer::GetUniformMap( BufferIndex bufferIndex ) const +const CollectedUniformMap& Renderer::GetUniformMap(BufferIndex bufferIndex) const { return mCollectedUniformMap[bufferIndex]; } -Renderer::Opacity Renderer::GetOpacity( BufferIndex updateBufferIndex, const Node& node ) const +Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, const Node& node) const { - Renderer::Opacity opacity = Renderer::OPAQUE; + Renderer::OpacityType opacityType = Renderer::OPAQUE; - switch( mBlendMode ) + if(node.IsTransparent()) { + return Renderer::TRANSPARENT; + } + + switch(mBlendMode) + { + case BlendMode::ON_WITHOUT_CULL: // If the renderer should always be use blending and never want to be transparent by alpha. + { + opacityType = Renderer::TRANSLUCENT; + break; + } case BlendMode::ON: // If the renderer should always be use blending { - opacity = Renderer::TRANSLUCENT; + float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex]; + if(alpha <= FULLY_TRANSPARENT) + { + opacityType = Renderer::TRANSPARENT; + } + else + { + opacityType = Renderer::TRANSLUCENT; + } break; } case BlendMode::AUTO: { - bool shaderRequiresBlending( mShader->HintEnabled( Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT ) ); - if( shaderRequiresBlending || ( mTextureSet && mTextureSet->HasAlpha() ) ) + if(BlendingOptions::IsAdvancedBlendEquationIncluded(mBlendBitmask)) { - opacity = Renderer::TRANSLUCENT; + opacityType = Renderer::TRANSLUCENT; + break; } - else // renderer should determine opacity using the actor color + + bool shaderRequiresBlending(mShader->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT)); + if(shaderRequiresBlending || (mTextureSet && mTextureSet->HasAlpha())) { - float alpha = node.GetWorldColor( updateBufferIndex ).a; - if( alpha <= FULLY_TRANSPARENT ) - { - opacity = TRANSPARENT; - } - else if( alpha <= FULLY_OPAQUE ) - { - opacity = TRANSLUCENT; - } + opacityType = Renderer::TRANSLUCENT; } + + // renderer should determine opacity using the actor color + float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex]; + if(alpha <= FULLY_TRANSPARENT) + { + opacityType = Renderer::TRANSPARENT; + } + else if(alpha <= FULLY_OPAQUE) + { + opacityType = Renderer::TRANSLUCENT; + } + break; } case BlendMode::OFF: // the renderer should never use blending default: { - opacity = Renderer::OPAQUE; + opacityType = Renderer::OPAQUE; break; } } - return opacity; + return opacityType; } -void Renderer::TextureSetChanged() -{ - mResendFlag |= RESEND_DATA_PROVIDER; -} - -void Renderer::TextureSetDeleted() -{ - mTextureSet = NULL; - - mResendFlag |= RESEND_DATA_PROVIDER; -} -void Renderer::ConnectionsChanged( PropertyOwner& object ) +void Renderer::ConnectionsChanged(PropertyOwner& object) { // One of our child objects has changed it's connections. Ensure the uniform // map gets regenerated during PrepareRender mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; - - // Ensure the child object pointers get re-sent to the renderer - mResendFlag |= RESEND_DATA_PROVIDER; } void Renderer::ConnectedUniformMapChanged() @@ -656,7 +753,7 @@ void Renderer::ConnectedUniformMapChanged() mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; } -void Renderer::UniformMappingsChanged( const UniformMap& mappings ) +void Renderer::UniformMappingsChanged(const UniformMap& mappings) { // The mappings are either from PropertyOwner base class, or the Actor mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; @@ -664,12 +761,19 @@ void Renderer::UniformMappingsChanged( const UniformMap& mappings ) void Renderer::ObservedObjectDestroyed(PropertyOwner& owner) { - if( reinterpret_cast(mShader) == &owner ) + if(reinterpret_cast(mShader) == &owner) { - mShader = NULL; + mShader = nullptr; } } +void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size) +{ + mDrawCommands.clear(); + mDrawCommands.insert(mDrawCommands.end(), pDrawCommands, pDrawCommands + size); + mResendFlag |= RESEND_DRAW_COMMANDS; +} + } // namespace SceneGraph } // namespace Internal } // namespace Dali