X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Frenderers%2Frender-renderer.cpp;h=2c820941fa54f517964f1460972e853e3722fc44;hb=ee9d14cd99ad293d46b17dc2f3591cc061ec403c;hp=685c35328a9739163e8f114a7c08656069c8f8eb;hpb=867b6b981fd4b72ca0f7d737859d3ab65cfa08b8;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 685c353..2c82094 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -25,8 +25,8 @@ #include #include #include -#include -#include +#include +#include namespace Dali { @@ -37,8 +37,6 @@ namespace Internal namespace { -static Matrix gModelViewProjectionMatrix( false ); ///< a shared matrix to calculate the MVP matrix, dont want to store it in object to reduce storage overhead -static Matrix3 gNormalMatrix; ///< a shared matrix to calculate normal matrix, dont want to store it in object to reduce storage overhead /** * Helper to set view and projection matrices once per program @@ -88,17 +86,19 @@ inline void SetMatrices( Program& program, loc = program.GetUniformLocation( Program::UNIFORM_MVP_MATRIX ); if( Program::UNIFORM_UNKNOWN != loc ) { - Matrix::Multiply( gModelViewProjectionMatrix, modelViewMatrix, projectionMatrix ); - program.SetUniformMatrix4fv( loc, 1, gModelViewProjectionMatrix.AsFloat() ); + Matrix modelViewProjectionMatrix(false); + Matrix::Multiply( modelViewProjectionMatrix, modelViewMatrix, projectionMatrix ); + program.SetUniformMatrix4fv( loc, 1, modelViewProjectionMatrix.AsFloat() ); } loc = program.GetUniformLocation( Program::UNIFORM_NORMAL_MATRIX ); if( Program::UNIFORM_UNKNOWN != loc ) { - gNormalMatrix = modelViewMatrix; - gNormalMatrix.Invert(); - gNormalMatrix.Transpose(); - program.SetUniformMatrix3fv( loc, 1, gNormalMatrix.AsFloat() ); + Matrix3 normalMatrix; + normalMatrix = modelViewMatrix; + normalMatrix.Invert(); + normalMatrix.Transpose(); + program.SetUniformMatrix3fv( loc, 1, normalMatrix.AsFloat() ); } } @@ -109,8 +109,8 @@ namespace Render Renderer* Renderer::New( SceneGraph::RenderDataProvider* dataProvider, Render::Geometry* geometry, - unsigned int blendingBitmask, - const Vector4* blendColor, + uint32_t blendingBitmask, + const Vector4& blendColor, FaceCullingMode::Type faceCullingMode, bool preMultipliedAlphaEnabled, DepthWriteMode::Type depthWriteMode, @@ -125,8 +125,8 @@ Renderer* Renderer::New( SceneGraph::RenderDataProvider* dataProvider, Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider, Render::Geometry* geometry, - unsigned int blendingBitmask, - const Vector4* blendColor, + uint32_t blendingBitmask, + const Vector4& blendColor, FaceCullingMode::Type faceCullingMode, bool preMultipliedAlphaEnabled, DepthWriteMode::Type depthWriteMode, @@ -134,11 +134,11 @@ Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider, DepthFunction::Type depthFunction, StencilParameters& stencilParameters ) : mRenderDataProvider( dataProvider ), - mContext( NULL), - mTextureCache( NULL ), + mContext( nullptr), mGeometry( geometry ), mUniformIndexMap(), mAttributesLocation(), + mUniformsHash(), mStencilParameters( stencilParameters ), mBlendingOptions(), mIndexedDrawFirstElement( 0 ), @@ -149,50 +149,34 @@ Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider, mDepthTestMode( depthTestMode ), mUpdateAttributesLocation( true ), mPremultipledAlphaEnabled( preMultipliedAlphaEnabled ), - mBatchingEnabled( false ) + mShaderChanged( false ), + mUpdated( true ) { - if( blendingBitmask != 0u ) + if( blendingBitmask != 0u ) { mBlendingOptions.SetBitmask( blendingBitmask ); } - if( blendColor ) - { - mBlendingOptions.SetBlendColor( *blendColor ); - } + mBlendingOptions.SetBlendColor( blendColor ); } -void Renderer::Initialize( Context& context, SceneGraph::TextureCache& textureCache ) +void Renderer::Initialize( Context& context ) { mContext = &context; - mTextureCache = &textureCache; -} - -Renderer::~Renderer() -{ } -void Renderer::SetRenderDataProvider( SceneGraph::RenderDataProvider* dataProvider ) -{ - mRenderDataProvider = dataProvider; - mUpdateAttributesLocation = true; - - //Check that the number of textures match the number of samplers in the shader - size_t textureCount = dataProvider->GetNewTextures().size(); - Program* program = dataProvider->GetShader().GetProgram(); - if( program && program->GetActiveSamplerCount() != textureCount ) - { - DALI_LOG_WARNING("The number of active samplers in the shader(%lu) does not match the number of textures in the TextureSet(%lu)\n", - program->GetActiveSamplerCount(), - textureCount ); - } -} +Renderer::~Renderer() = default; void Renderer::SetGeometry( Render::Geometry* geometry ) { mGeometry = geometry; mUpdateAttributesLocation = true; } +void Renderer::SetDrawCommands( Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size ) +{ + mDrawCommands.clear(); + mDrawCommands.insert( mDrawCommands.end(), pDrawCommands, pDrawCommands+size ); +} void Renderer::SetBlending( Context& context, bool blend ) { @@ -220,6 +204,8 @@ void Renderer::SetBlending( Context& context, bool blend ) context.BlendEquationSeparate( mBlendingOptions.GetBlendEquationRgb(), mBlendingOptions.GetBlendEquationAlpha() ); } + + mUpdated = true; } void Renderer::GlContextDestroyed() @@ -239,27 +225,32 @@ void Renderer::SetUniforms( BufferIndex bufferIndex, const SceneGraph::NodeDataP const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap(); if( uniformMapDataProvider.GetUniformMapChanged( bufferIndex ) || - node.GetUniformMapChanged(bufferIndex)) + node.GetUniformMapChanged(bufferIndex) || + mUniformIndexMap.Count() == 0 || + mShaderChanged ) { + // Reset shader pointer + mShaderChanged = false; + const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex ); const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap( bufferIndex ); - unsigned int maxMaps = uniformMap.Count() + uniformMapNode.Count(); + uint32_t maxMaps = static_cast( uniformMap.Count() + uniformMapNode.Count() ); // 4,294,967,295 maps should be enough mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size mUniformIndexMap.Resize( maxMaps ); - unsigned int mapIndex(0); + uint32_t mapIndex = 0; for(; mapIndex < uniformMap.Count() ; ++mapIndex ) { mUniformIndexMap[mapIndex].propertyValue = uniformMap[mapIndex]->propertyPtr; mUniformIndexMap[mapIndex].uniformIndex = program.RegisterUniform( uniformMap[mapIndex]->uniformName ); } - for( unsigned int nodeMapIndex = 0; nodeMapIndex < uniformMapNode.Count() ; ++nodeMapIndex ) + for( uint32_t nodeMapIndex = 0; nodeMapIndex < uniformMapNode.Count() ; ++nodeMapIndex ) { - unsigned int uniformIndex = program.RegisterUniform( uniformMapNode[nodeMapIndex]->uniformName ); + uint32_t uniformIndex = program.RegisterUniform( uniformMapNode[nodeMapIndex]->uniformName ); bool found(false); - for( unsigned int i(0); i& boundTextures ) { - unsigned int textureUnit = 0; + uint32_t textureUnit = 0; bool result = true; GLint uniformLocation(-1); std::vector& samplers( mRenderDataProvider->GetSamplers() ); - std::vector& newTextures( mRenderDataProvider->GetNewTextures() ); - for( size_t i(0); i& textures( mRenderDataProvider->GetTextures() ); + for( uint32_t i = 0; i < static_cast( textures.size() ) && result; ++i ) // not expecting more than uint32_t of textures { - if( newTextures[i] ) + if( textures[i] ) { - result = newTextures[i]->Bind(context, textureUnit, samplers[i] ); + result = textures[i]->Bind(context, textureUnit, samplers[i] ); + boundTextures.PushBack( textures[i]->GetId() ); if( result && program.GetSamplerUniformLocation( i, uniformLocation ) ) { program.SetUniform1i( uniformLocation, textureUnit ); @@ -392,41 +384,49 @@ bool Renderer::BindTextures( Context& context, SceneGraph::TextureCache& texture void Renderer::SetFaceCullingMode( FaceCullingMode::Type mode ) { mFaceCullingMode = mode; + mUpdated = true; } -void Renderer::SetBlendingBitMask( unsigned int bitmask ) +void Renderer::SetBlendingBitMask( uint32_t bitmask ) { mBlendingOptions.SetBitmask( bitmask ); + mUpdated = true; } -void Renderer::SetBlendColor( const Vector4* color ) +void Renderer::SetBlendColor( const Vector4& color ) { - mBlendingOptions.SetBlendColor( *color ); + mBlendingOptions.SetBlendColor( color ); + mUpdated = true; } -void Renderer::SetIndexedDrawFirstElement( size_t firstElement ) +void Renderer::SetIndexedDrawFirstElement( uint32_t firstElement ) { mIndexedDrawFirstElement = firstElement; + mUpdated = true; } -void Renderer::SetIndexedDrawElementsCount( size_t elementsCount ) +void Renderer::SetIndexedDrawElementsCount( uint32_t elementsCount ) { mIndexedDrawElementsCount = elementsCount; + mUpdated = true; } void Renderer::EnablePreMultipliedAlpha( bool enable ) { mPremultipledAlphaEnabled = enable; + mUpdated = true; } void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode ) { mDepthWriteMode = depthWriteMode; + mUpdated = true; } void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode ) { mDepthTestMode = depthTestMode; + mUpdated = true; } DepthWriteMode::Type Renderer::GetDepthWriteMode() const @@ -442,6 +442,7 @@ DepthTestMode::Type Renderer::GetDepthTestMode() const void Renderer::SetDepthFunction( DepthFunction::Type depthFunction ) { mDepthFunction = depthFunction; + mUpdated = true; } DepthFunction::Type Renderer::GetDepthFunction() const @@ -452,6 +453,7 @@ DepthFunction::Type Renderer::GetDepthFunction() const void Renderer::SetRenderMode( RenderMode::Type renderMode ) { mStencilParameters.renderMode = renderMode; + mUpdated = true; } RenderMode::Type Renderer::GetRenderMode() const @@ -462,6 +464,7 @@ RenderMode::Type Renderer::GetRenderMode() const void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction ) { mStencilParameters.stencilFunction = stencilFunction; + mUpdated = true; } StencilFunction::Type Renderer::GetStencilFunction() const @@ -472,6 +475,7 @@ StencilFunction::Type Renderer::GetStencilFunction() const void Renderer::SetStencilFunctionMask( int stencilFunctionMask ) { mStencilParameters.stencilFunctionMask = stencilFunctionMask; + mUpdated = true; } int Renderer::GetStencilFunctionMask() const @@ -482,6 +486,7 @@ int Renderer::GetStencilFunctionMask() const void Renderer::SetStencilFunctionReference( int stencilFunctionReference ) { mStencilParameters.stencilFunctionReference = stencilFunctionReference; + mUpdated = true; } int Renderer::GetStencilFunctionReference() const @@ -492,6 +497,7 @@ int Renderer::GetStencilFunctionReference() const void Renderer::SetStencilMask( int stencilMask ) { mStencilParameters.stencilMask = stencilMask; + mUpdated = true; } int Renderer::GetStencilMask() const @@ -502,6 +508,7 @@ int Renderer::GetStencilMask() const void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail ) { mStencilParameters.stencilOperationOnFail = stencilOperationOnFail; + mUpdated = true; } StencilOperation::Type Renderer::GetStencilOperationOnFail() const @@ -512,6 +519,7 @@ StencilOperation::Type Renderer::GetStencilOperationOnFail() const void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail ) { mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail; + mUpdated = true; } StencilOperation::Type Renderer::GetStencilOperationOnZFail() const @@ -522,6 +530,7 @@ StencilOperation::Type Renderer::GetStencilOperationOnZFail() const void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass ) { mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass; + mUpdated = true; } StencilOperation::Type Renderer::GetStencilOperationOnZPass() const @@ -529,48 +538,87 @@ StencilOperation::Type Renderer::GetStencilOperationOnZPass() const return mStencilParameters.stencilOperationOnZPass; } -void Renderer::SetBatchingEnabled( bool batchingEnabled ) +void Renderer::Upload( Context& context ) { - mBatchingEnabled = batchingEnabled; + mGeometry->Upload( context ); } void Renderer::Render( Context& context, - SceneGraph::TextureCache& textureCache, BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, - SceneGraph::Shader& defaultShader, const Matrix& modelMatrix, const Matrix& modelViewMatrix, const Matrix& viewMatrix, const Matrix& projectionMatrix, const Vector3& size, - Render::Geometry* externalGeometry, - bool blend ) + bool blend, + Vector& boundTextures, + const Dali::Internal::SceneGraph::RenderInstruction& instruction, + uint32_t queueIndex ) { + // Before doing anything test if the call happens in the right queue + if( mDrawCommands.empty() && queueIndex > 0 ) + { + return; + } + + // Prepare commands + std::vector commands; + for( auto& cmd : mDrawCommands ) + { + if(cmd.queue == queueIndex) + { + commands.emplace_back( &cmd ); + } + } + + // Have commands but nothing to be drawn - abort + if(!mDrawCommands.empty() && commands.empty()) + { + return; + } + // Get the program to use: Program* program = mRenderDataProvider->GetShader().GetProgram(); if( !program ) { - // if program is NULL it means this is a custom shader with non matching geometry type so we need to use default shaders program - program = defaultShader.GetProgram(); - DALI_ASSERT_DEBUG( program && "Default shader should always have a program available." ); - if( !program ) - { - DALI_LOG_ERROR( "Failed to get program for shader at address %p.\n", (void*)&mRenderDataProvider->GetShader() ); - return; - } + DALI_LOG_ERROR( "Failed to get program for shader at address %p.\n", reinterpret_cast< void* >( &mRenderDataProvider->GetShader() ) ); + return; } //Set cull face mode - context.CullFace( mFaceCullingMode ); - - //Set blending mode - SetBlending( context, blend ); + const Dali::Internal::SceneGraph::Camera* cam = instruction.GetCamera(); + if (cam->GetReflectionUsed()) + { + auto adjFaceCullingMode = mFaceCullingMode; + switch( mFaceCullingMode ) + { + case FaceCullingMode::Type::FRONT: + { + adjFaceCullingMode = FaceCullingMode::Type::BACK; + break; + } + case FaceCullingMode::Type::BACK: + { + adjFaceCullingMode = FaceCullingMode::Type::FRONT; + break; + } + default: + { + // nothing to do, leave culling as it is + } + } + context.CullFace( adjFaceCullingMode ); + } + else + { + context.CullFace( mFaceCullingMode ); + } // Take the program into use so we can send uniforms to it program->Use(); - if( DALI_LIKELY( BindTextures( context, textureCache, *program ) ) ) + if( DALI_LIKELY( BindTextures( context, *program, boundTextures ) ) ) { // Only set up and draw if we have textures and they are all valid @@ -584,24 +632,47 @@ void Renderer::Render( Context& context, const Vector4& color = node.GetRenderColor( bufferIndex ); if( mPremultipledAlphaEnabled ) { - program->SetUniform4f( loc, color.r*color.a, color.g*color.a, color.b*color.a, color.a ); + float alpha = color.a * mRenderDataProvider->GetOpacity( bufferIndex ); + program->SetUniform4f( loc, color.r * alpha, color.g * alpha, color.b * alpha, alpha ); } else { - program->SetUniform4f( loc, color.r, color.g, color.b, color.a ); + program->SetUniform4f( loc, color.r, color.g, color.b, color.a * mRenderDataProvider->GetOpacity( bufferIndex ) ); } } SetUniforms( bufferIndex, node, size, *program ); - Render::Geometry* geometry = externalGeometry ? externalGeometry : mGeometry; - if( mUpdateAttributesLocation || geometry->AttributesChanged() ) + if( mUpdateAttributesLocation || mGeometry->AttributesChanged() ) { - geometry->GetAttributeLocationFromProgram( mAttributesLocation, *program, bufferIndex ); + mGeometry->GetAttributeLocationFromProgram( mAttributesLocation, *program, bufferIndex ); mUpdateAttributesLocation = false; } - geometry->UploadAndDraw( context, bufferIndex, mAttributesLocation, mIndexedDrawFirstElement, mIndexedDrawElementsCount ); + if(mDrawCommands.empty()) + { + SetBlending( context, blend ); + + mGeometry->Draw( context, + bufferIndex, + mAttributesLocation, + mIndexedDrawFirstElement, + mIndexedDrawElementsCount ); + } + else + { + for(auto& cmd : commands ) + { + if(cmd->queue == queueIndex ) + { + //Set blending mode + SetBlending(context, cmd->queue == DevelRenderer::RENDER_QUEUE_OPAQUE ? false : blend); + mGeometry->Draw(context, bufferIndex, mAttributesLocation, + cmd->firstIndex, cmd->elementCount); + } + } + } + mUpdated = false; } } @@ -612,6 +683,55 @@ void Renderer::SetSortAttributes( BufferIndex bufferIndex, sortAttributes.geometry = mGeometry; } +void Renderer::SetShaderChanged( bool value ) +{ + mShaderChanged = value; +} + +bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider* node) +{ + if (mUpdated) + { + mUpdated = false; + return true; + } + + if (mShaderChanged || mUpdateAttributesLocation || mGeometry->AttributesChanged()) + { + return true; + } + + for( const auto& texture : mRenderDataProvider->GetTextures() ) + { + if (texture && texture->IsNativeImage()) + { + return true; + } + } + + uint64_t hash = 0xc70f6907UL; + const SceneGraph::CollectedUniformMap& uniformMapNode = node->GetUniformMap( bufferIndex ); + for (const auto* uniformProperty : uniformMapNode) + { + hash = uniformProperty->propertyPtr->Hash(bufferIndex, hash); + } + + const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap(); + const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex ); + for (const auto* uniformProperty : uniformMap) + { + hash = uniformProperty->propertyPtr->Hash(bufferIndex, hash); + } + + if (mUniformsHash != hash) + { + mUniformsHash = hash; + return true; + } + + return false; +} + } // namespace SceneGraph } // namespace Internal