X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Frendering%2Fscene-graph-renderer.cpp;h=331a93de2110e47f6ed2be5720f54a9da4f80928;hb=9d8818db1ee5ad9497cb7698be2a4752f6ecf50e;hp=0d79152134719e084527a03c2b1026dec14e3624;hpb=777cc8604ba7d780fd5d424fe15824dfab22d0c7;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 0d79152..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) 2015 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. @@ -17,185 +17,204 @@ // CLASS HEADER #include "scene-graph-renderer.h" -// INTERNAL HEADERS -#include +// INTERNAL INCLUDES +#include +#include +#include +#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); } - //@todo MESH_REWORK Use memcpy to copy ptrs from one array to the other } } -// flags for resending data to renderer +// Flags for re-sending 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_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 }; -} - -namespace Dali -{ -namespace Internal -{ -namespace SceneGraph -{ +} // Anonymous namespace Renderer* Renderer::New() { - return new ( gRendererMemoryPool.AllocateRawThreadSafe() ) Renderer(); + return new(gRendererMemoryPool.AllocateRawThreadSafe()) Renderer(); } Renderer::Renderer() -:mSceneController(0), - mRenderer(NULL), - mMaterial(NULL), - mGeometry(NULL), - mBlendColor(NULL), - mBlendBitmask(0u), - mFaceCullingMode( Dali::Renderer::NONE ), - mBlendingMode( Dali::BlendingMode::AUTO ), - mReferenceCount(0), - mRegenerateUniformMap(0), - mResendFlag(0), - mResourcesReady(false), - mFinishedResourceAcquisition(false), - mDepthIndex(0) -{ - mUniformMapChanged[0]=false; - mUniformMapChanged[1]=false; +: 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 (mMaterial) + if(mTextureSet) { - mMaterial->RemoveConnectionObserver(*this); - mMaterial=NULL; + mTextureSet = nullptr; } - if (mGeometry) + if(mShader) { - mGeometry->RemoveConnectionObserver(*this); - mGeometry=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) { - mResourcesReady = false; - mFinishedResourceAcquisition = false; - - // 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 ) ) + if(mRegenerateUniformMap == UNIFORM_MAP_READY) { - mMaterial->GetResourcesStatus( mResourcesReady, mFinishedResourceAcquisition ); + mUniformMapChanged[updateBufferIndex] = false; } - - if( mRegenerateUniformMap > UNIFORM_MAP_READY ) + else { - DALI_ASSERT_DEBUG( mGeometry != NULL && "No geometry available in DoPrepareRender()" ); - DALI_ASSERT_DEBUG( mMaterial != NULL && "No geometry available in DoPrepareRender()" ); - - if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP) + 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 ); - AddMappings( localMap, mMaterial->GetUniformMap() ); - AddMappings( localMap, mMaterial->GetShader()->GetUniformMap() ); - AddMappings( localMap, mGeometry->GetUniformMap() ); + auto size = rendererUniformMap.Count(); + if(mShader) + { + size += mShader->GetUniformMap().Count(); + } + + localMap.Reserve(size); + + AddMappings(localMap, rendererUniformMap); + if(mShader) + { + 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; } @@ -205,211 +224,444 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex ) mRegenerateUniformMap--; } - if( mResendFlag == 0 ) - { - return; - } + bool rendererUpdated = mUniformMapChanged[updateBufferIndex] || mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY; - if( mResendFlag & RESEND_DATA_PROVIDER ) + if(mResendFlag != 0) { - RenderDataProvider* dataProvider = NewRenderDataProvider(); + if(mResendFlag & RESEND_GEOMETRY) + { + 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 ); - mResendFlag &= ~RESEND_DATA_PROVIDER; - } + 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 ) - { - // 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) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode); + } - typedef MessageValue1< Render::Renderer, RenderGeometry* > DerivedType; - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + if(mResendFlag & RESEND_BLEND_BIT_MASK) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask); + } - new (slot) DerivedType( mRenderer, &Render::Renderer::SetGeometry, geometry ); - mResendFlag &= ~RESEND_GEOMETRY; - } + if(mResendFlag & RESEND_BLEND_COLOR) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendColor, GetBlendColor()); + } - 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::Renderer::SetFaceCullingMode, mFaceCullingMode ); - mResendFlag &= ~RESEND_FACE_CULLING_MODE; - } + if(mResendFlag & RESEND_PREMULTIPLIED_ALPHA) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled); + } - 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 ); - mResendFlag &= ~RESEND_BLEND_BIT_MASK; - } + if(mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement); + } - 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; - } + if(mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount); + } - 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_DEPTH_WRITE_MODE) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode); + } + + if(mResendFlag & RESEND_DEPTH_TEST_MODE) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthTestMode, mDepthTestMode); + } + + if(mResendFlag & RESEND_DEPTH_FUNCTION) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction); + } + + if(mResendFlag & RESEND_RENDER_MODE) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderMode, mStencilParameters.renderMode); + } + + if(mResendFlag & RESEND_STENCIL_FUNCTION) + { + 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_MASK) + { + 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_REFERENCE) + { + 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_MASK) + { + 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_OPERATION_ON_FAIL) + { + 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_Z_FAIL) + { + 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_PASS) + { + using DerivedType = MessageValue1; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType)); + new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass); + } + + if(mResendFlag & RESEND_SHADER) + { + 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::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 ); + mTextureSet = textureSet; mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; +} - mResendFlag |= RESEND_DATA_PROVIDER; +const Vector* Renderer::GetTextures() const +{ + return mTextureSet ? &(mTextureSet->GetTextures()) : nullptr; +} + +const Vector* Renderer::GetSamplers() const +{ + return mTextureSet ? &(mTextureSet->GetSamplers()) : nullptr; } -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_GEOMETRY | RESEND_SHADER; +} - if( mRenderer ) +void Renderer::SetGeometry(Render::Geometry* geometry) +{ + DALI_ASSERT_DEBUG(geometry != NULL && "Geometry pointer is NULL"); + mGeometry = geometry; + + if(mRenderer) { mResendFlag |= RESEND_GEOMETRY; } } -void Renderer::SetDepthIndex( int depthIndex ) +void Renderer::SetDepthIndex(int depthIndex) { mDepthIndex = depthIndex; } -void Renderer::SetFaceCullingMode( unsigned int faceCullingMode ) +void Renderer::SetFaceCullingMode(FaceCullingMode::Type faceCullingMode) { - mFaceCullingMode = static_cast(faceCullingMode); + mFaceCullingMode = faceCullingMode; mResendFlag |= RESEND_FACE_CULLING_MODE; } -void Renderer::SetBlendingMode( unsigned int blendingMode ) +FaceCullingMode::Type Renderer::GetFaceCullingMode() const +{ + return mFaceCullingMode; +} + +void Renderer::SetBlendMode(BlendMode::Type blendingMode) +{ + mBlendMode = blendingMode; +} + +BlendMode::Type Renderer::GetBlendMode() const { - mBlendingMode = static_cast< BlendingMode::Type >( blendingMode ); + return mBlendMode; } -void Renderer::SetBlendingOptions( unsigned int options ) +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 +{ + return mBlendBitmask; +} + +void Renderer::SetBlendColor(const Vector4& blendColor) { - if( !mBlendColor ) + if(blendColor == Color::TRANSPARENT) { - mBlendColor = new Vector4( blendColor ); + mBlendColor = nullptr; } else { - *mBlendColor = blendColor; + if(!mBlendColor) + { + mBlendColor = new Vector4(blendColor); + } + else + { + *mBlendColor = blendColor; + } } mResendFlag |= RESEND_BLEND_COLOR; } -void Renderer::EnablePreMultipliedAlpha( bool preMultipled ) +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; +} + +uint32_t Renderer::GetIndexedDrawFirstElement() const +{ + return mIndexedDrawFirstElement; +} + +void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount) +{ + mIndexedDrawElementsCount = elementsCount; + mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT; +} + +uint32_t Renderer::GetIndexedDrawElementsCount() const +{ + return mIndexedDrawElementsCount; +} + +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() +bool Renderer::IsPreMultipliedAlphaEnabled() const { - ++mReferenceCount; - if( !mRenderer) - { - RenderDataProvider* dataProvider = NewRenderDataProvider(); - - RenderGeometry* renderGeometry = mGeometry->GetRenderGeometry(mSceneController); - mRenderer = Render::Renderer::New( dataProvider, renderGeometry, - mBlendBitmask, mBlendColor, - static_cast< Dali::Renderer::FaceCullingMode >( mFaceCullingMode ), - mPremultipledAlphaEnabled ); - mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer ); - mResendFlag = 0; - } + return mPremultipledAlphaEnabled; } -//Called when the node with this renderer has gone out of the stage -void Renderer::OnStageDisconnect() +void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode) { - --mReferenceCount; - if( mReferenceCount == 0 ) - { - mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer ); - if( mGeometry ) - { - mGeometry->OnRendererDisconnect(); - } - mRenderer = NULL; - } + mDepthWriteMode = depthWriteMode; + mResendFlag |= RESEND_DEPTH_WRITE_MODE; } -//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 ) +DepthWriteMode::Type Renderer::GetDepthWriteMode() const { - mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; - mSceneController = &sceneController; + return mDepthWriteMode; } +void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode) +{ + mDepthTestMode = depthTestMode; + mResendFlag |= RESEND_DEPTH_TEST_MODE; +} -//Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced ) -void Renderer::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex ) +DepthTestMode::Type Renderer::GetDepthTestMode() const { - //Remove renderer from RenderManager - if( mRenderer ) - { - mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer ); - mRenderer = NULL; - mSceneController = NULL; - } + return mDepthTestMode; } -RenderDataProvider* Renderer::NewRenderDataProvider() +void Renderer::SetDepthFunction(DepthFunction::Type depthFunction) { - RenderDataProvider* dataProvider = new RenderDataProvider(); + mDepthFunction = depthFunction; + mResendFlag |= RESEND_DEPTH_FUNCTION; +} + +DepthFunction::Type Renderer::GetDepthFunction() const +{ + return mDepthFunction; +} - dataProvider->mUniformMapDataProvider = this; - dataProvider->mShader = mMaterial->GetShader(); +void Renderer::SetRenderMode(RenderMode::Type mode) +{ + mStencilParameters.renderMode = mode; + mResendFlag |= RESEND_RENDER_MODE; +} - size_t textureCount( mMaterial->GetTextureCount() ); - dataProvider->mTextures.resize( textureCount ); - for( unsigned int i(0); i(mFaceCullingMode), mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters); + + OwnerPointer 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) +{ + //Remove renderer from RenderManager + if(mRenderer) { - dataProvider->mTextures[i] = Render::Texture( mMaterial->GetTextureUniformName(i), - mMaterial->GetTextureId(i), - mMaterial->GetTextureSampler(i)); + mSceneController->GetRenderMessageDispatcher().RemoveRenderer(*mRenderer); + mRenderer = nullptr; } - - return dataProvider; + mSceneController = nullptr; } Render::Renderer& Renderer::GetRenderer() @@ -417,70 +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]; -}; - -void Renderer::GetReadyAndComplete( bool& ready, bool& complete ) const -{ - ready = mResourcesReady; - complete = mFinishedResourceAcquisition; } -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; + + if(node.IsTransparent()) + { + return Renderer::TRANSPARENT; + } - if( mMaterial ) + switch(mBlendMode) { - switch( mBlendingMode ) + case BlendMode::ON_WITHOUT_CULL: // If the renderer should always be use blending and never want to be transparent by alpha. { - case BlendingMode::ON: // If the renderer should always be use blending + opacityType = Renderer::TRANSLUCENT; + break; + } + case BlendMode::ON: // If the renderer should always be use blending + { + float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex]; + if(alpha <= FULLY_TRANSPARENT) { - opacity = Renderer::TRANSLUCENT; - break; + opacityType = Renderer::TRANSPARENT; } - case BlendingMode::AUTO: + else { - if(mMaterial->IsTranslucent() ) // If the renderer should determine opacity using the material - { - opacity = Renderer::TRANSLUCENT; - } - else // renderer should determine opacity using the actor color - { - float alpha = node.GetWorldColor( updateBufferIndex ).a; - if( alpha <= FULLY_TRANSPARENT ) - { - opacity = TRANSPARENT; - } - else if( alpha <= FULLY_OPAQUE ) - { - opacity = TRANSLUCENT; - } - } - break; + opacityType = Renderer::TRANSLUCENT; } - case BlendingMode::OFF: // the renderer should never use blending - default: + break; + } + case BlendMode::AUTO: + { + if(BlendingOptions::IsAdvancedBlendEquationIncluded(mBlendBitmask)) { - opacity = Renderer::OPAQUE; + opacityType = Renderer::TRANSLUCENT; break; } + + bool shaderRequiresBlending(mShader->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT)); + if(shaderRequiresBlending || (mTextureSet && mTextureSet->HasAlpha())) + { + 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: + { + opacityType = Renderer::OPAQUE; + break; } } - return opacity; + return opacityType; } -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() @@ -488,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; @@ -496,16 +761,19 @@ 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 = 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