/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
#include <dali/internal/render/common/render-instruction-container.h>
#include <dali/internal/render/shaders/scene-graph-shader.h>
#include <dali/internal/render/renderers/render-renderer.h>
-#include <dali/internal/render/renderers/render-property-buffer.h>
#include <dali/internal/update/nodes/scene-graph-layer.h>
namespace
* @param isLayer3d Whether we are processing a 3D layer or not
* @param cull Whether frustum culling is enabled or not
*/
-inline void AddRendererToRenderList( BufferIndex updateBufferIndex,
- RenderList& renderList,
- Renderable& renderable,
- const Matrix& viewMatrix,
- SceneGraph::Camera& camera,
- bool isLayer3d,
- bool cull )
+inline void AddRendererToRenderList(BufferIndex updateBufferIndex,
+ RenderList& renderList,
+ Renderable& renderable,
+ const Matrix& viewMatrix,
+ SceneGraph::Camera& camera,
+ bool isLayer3d,
+ bool cull)
{
- bool inside( true );
+ bool inside(true);
Node* node = renderable.mNode;
- if( cull && renderable.mRenderer && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) )
+ if (cull && renderable.mRenderer && !renderable.mRenderer->GetShader().HintEnabled(Dali::Shader::Hint::MODIFIES_GEOMETRY))
{
const Vector4& boundingSphere = node->GetBoundingSphere();
- inside = ( boundingSphere.w > Math::MACHINE_EPSILON_1000 ) &&
- ( camera.CheckSphereInFrustum( updateBufferIndex, Vector3( boundingSphere ), boundingSphere.w ) );
+ inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) &&
+ (camera.CheckSphereInFrustum(updateBufferIndex, Vector3(boundingSphere), boundingSphere.w));
}
- if( inside )
+ if (inside)
{
Renderer::OpacityType opacityType = renderable.mRenderer ? renderable.mRenderer->GetOpacityType( updateBufferIndex, *renderable.mNode ) : Renderer::OPAQUE;
- if( opacityType != Renderer::TRANSPARENT || node->GetClippingMode() == ClippingMode::CLIP_CHILDREN )
+ if (opacityType != Renderer::TRANSPARENT || node->GetClippingMode() == ClippingMode::CLIP_CHILDREN)
{
// Get the next free RenderItem.
RenderItem& item = renderList.GetNextFreeItem();
+ item.mIsUpdated = (item.mNode != renderable.mNode);
item.mNode = renderable.mNode;
- item.mIsOpaque = ( opacityType == Renderer::OPAQUE );
- item.mDepthIndex = 0;
- if(!isLayer3d)
+ bool prevIsOpaque = item.mIsOpaque;
+ item.mIsOpaque = (opacityType == Renderer::OPAQUE);
+ item.mIsUpdated |= (prevIsOpaque != item.mIsOpaque);
+
+ Vector4 prevColor = item.mColor;
+ item.mColor = renderable.mNode->GetColor(updateBufferIndex);
+ item.mIsUpdated |= (prevColor != item.mColor);
+
+ int prevDepthIndex = item.mDepthIndex;
+ item.mDepthIndex = 0;
+ if (!isLayer3d)
{
item.mDepthIndex = renderable.mNode->GetDepthIndex();
}
- if( DALI_LIKELY( renderable.mRenderer ) )
+ Render::Renderer* prevRenderer = item.mRenderer;
+ if (DALI_LIKELY(renderable.mRenderer))
{
- item.mRenderer = &renderable.mRenderer->GetRenderer();
- item.mTextureSet = renderable.mRenderer->GetTextures();
+ item.mRenderer = &renderable.mRenderer->GetRenderer();
+ const void* prevTextureSet = item.mTextureSet;
+ item.mTextureSet = renderable.mRenderer->GetTextures();
+ item.mIsUpdated |= (prevTextureSet != item.mTextureSet);
item.mDepthIndex += renderable.mRenderer->GetDepthIndex();
}
else
item.mRenderer = nullptr;
}
- // Save ModelView matrix onto the item.
- node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize );
+ item.mIsUpdated |= (prevDepthIndex != item.mDepthIndex);
+ item.mIsUpdated |= (prevRenderer != item.mRenderer);
+ item.mIsUpdated |= isLayer3d;
- Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix );
+ if (!item.mIsUpdated)
+ {
+ Matrix prevModelViewMatrix = item.mModelViewMatrix;
+ Vector3 prevSize = item.mSize;
+
+ // Save ModelView matrix onto the item.
+ node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize );
+ Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix );
+
+ item.mIsUpdated = ((prevSize != item.mSize) || (item.mModelViewMatrix != prevModelViewMatrix));
+ }
+ else
+ {
+ // Save ModelView matrix onto the item.
+ node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize );
+ Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix );
+ }
+
+ item.mUpdateSize = node->GetUpdateSizeHint();
+ if (item.mUpdateSize == Vector3::ZERO)
+ {
+ // RenderItem::CalculateViewportSpaceAABB cannot cope with z transform
+ // I don't use item.mModelMatrix.GetTransformComponents() for z transform, would be to slow
+ if (!isLayer3d && item.mModelMatrix.GetZAxis() == Vector3(0.0f, 0.0f, 1.0f))
+ {
+ item.mUpdateSize = item.mSize;
+ }
+ }
}
- node->SetCulled( updateBufferIndex, false );
+ node->SetCulled( updateBufferIndex, false );
}
else
{
- node->SetCulled( updateBufferIndex, true );
+ node->SetCulled( updateBufferIndex, true );
}
}
{
DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "AddRenderersToRenderList()\n");
- unsigned int rendererCount( renderers.Size() );
- for( unsigned int i(0); i < rendererCount; ++i )
+ for( auto&& renderer : renderers )
{
AddRendererToRenderList( updateBufferIndex,
renderList,
- renderers[i],
+ renderer,
viewMatrix,
camera,
isLayer3d,
- cull );
+ cull);
}
}
RenderableContainer& renderables )
{
bool retValue = false;
- size_t renderableCount = renderables.Size();
+ uint32_t renderableCount = static_cast<uint32_t>( renderables.Size() );
// Check that the cached list originates from this layer and that the counts match
if( ( renderList.GetSourceLayer() == &layer )&&
( renderList.GetCachedItemCount() == renderableCount ) )
// Therefore we check a combined sum of all renderer addresses.
size_t checkSumNew = 0;
size_t checkSumOld = 0;
- for( size_t index = 0; index < renderableCount; ++index )
+ for( uint32_t index = 0; index < renderableCount; ++index )
{
const Render::Renderer& renderer = renderables[index].mRenderer->GetRenderer();
- checkSumNew += size_t( &renderer );
- checkSumOld += size_t( &renderList.GetRenderer( index ) );
+ checkSumNew += reinterpret_cast<std::size_t>( &renderer );
+ checkSumOld += reinterpret_cast<std::size_t>( &renderList.GetRenderer( index ) );
}
if( checkSumNew == checkSumOld )
{
retValue = true;
}
}
+
return retValue;
}
inline void RenderInstructionProcessor::SortRenderItems( BufferIndex bufferIndex, RenderList& renderList, Layer& layer, bool respectClippingOrder )
{
- const size_t renderableCount = renderList.Count();
+ const uint32_t renderableCount = static_cast<uint32_t>( renderList.Count() );
// Reserve space if needed.
- const unsigned int oldcapacity = mSortingHelper.size();
+ const uint32_t oldcapacity = static_cast<uint32_t>( mSortingHelper.size() );
if( oldcapacity < renderableCount )
{
mSortingHelper.reserve( renderableCount );
// Using an if and two for-loops rather than if inside for as its better for branch prediction.
if( layer.UsesDefaultSortFunction() )
{
- for( size_t index = 0; index < renderableCount; ++index )
+ for( uint32_t index = 0; index < renderableCount; ++index )
{
RenderItem& item = renderList.GetItem( index );
mSortingHelper[ index ].textureSet = item.mTextureSet;
// The default sorting function should get inlined here.
- mSortingHelper[ index ].zValue = Internal::Layer::ZValue( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex;
+ mSortingHelper[ index ].zValue = Internal::Layer::ZValue( item.mModelViewMatrix.GetTranslation3() ) - static_cast<float>( item.mDepthIndex );
// Keep the renderitem pointer in the helper so we can quickly reorder items after sort.
mSortingHelper[ index ].renderItem = &item;
else
{
const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction();
- for( size_t index = 0; index < renderableCount; ++index )
+ for( uint32_t index = 0; index < renderableCount; ++index )
{
RenderItem& item = renderList.GetItem( index );
mSortingHelper[ index ].textureSet = item.mTextureSet;
- mSortingHelper[ index ].zValue = (*sortFunction)( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex;
+ mSortingHelper[ index ].zValue = (*sortFunction)( item.mModelViewMatrix.GetTranslation3() ) - static_cast<float>( item.mDepthIndex );
// Keep the RenderItem pointer in the helper so we can quickly reorder items after sort.
mSortingHelper[ index ].renderItem = &item;
// Reorder / re-populate the RenderItems in the RenderList to correct order based on the sortinghelper.
DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "Sorted Transparent List:\n");
RenderItemContainer::Iterator renderListIter = renderList.GetContainer().Begin();
- for( unsigned int index = 0; index < renderableCount; ++index, ++renderListIter )
+ for( uint32_t index = 0; index < renderableCount; ++index, ++renderListIter )
{
*renderListIter = mSortingHelper[ index ].renderItem;
DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, " sortedList[%d] = %p\n", index, mSortingHelper[ index ].renderItem->mRenderer);
{
// Retrieve the RenderInstruction buffer from the RenderInstructionContainer
// then populate with instructions.
- RenderInstruction& instruction = instructions.GetNextInstruction( updateBufferIndex );
- renderTask.PrepareRenderInstruction( instruction, updateBufferIndex );
+ RenderInstruction& instruction = renderTask.PrepareRenderInstruction( updateBufferIndex );
bool viewMatrixHasNotChanged = !renderTask.ViewMatrixUpdated();
bool isRenderListAdded = false;
+ bool isRootLayerDirty = false;
const Matrix& viewMatrix = renderTask.GetViewMatrix( updateBufferIndex );
SceneGraph::Camera& camera = renderTask.GetCamera();
const bool isLayer3D = layer.GetBehavior() == Dali::Layer::LAYER_3D;
RenderList* renderList = NULL;
+ if( layer.IsRoot() && ( layer.GetDirtyFlags() != NodePropertyFlags::NOTHING ) )
+ {
+ // If root-layer & dirty, i.e. a property has changed or a child has been deleted, then we need to ensure we render once more
+ isRootLayerDirty = true;
+ }
+
if( !layer.colorRenderables.Empty() )
{
RenderableContainer& renderables = layer.colorRenderables;
// Inform the render instruction that all renderers have been added and this frame is complete.
instruction.UpdateCompleted();
- if( !isRenderListAdded && !instruction.mIsClearColorSet )
+ if( isRenderListAdded || instruction.mIsClearColorSet || isRootLayerDirty )
{
- instructions.DiscardCurrentInstruction( updateBufferIndex );
+ instructions.PushBack( updateBufferIndex, &instruction );
}
}