X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Frenderers%2Frender-renderer.cpp;h=767a11d1d0a75dc23ab40c0f054c92d118f57650;hb=78690d4683391e2a67ee2bbd143c517bc385db86;hp=685c35328a9739163e8f114a7c08656069c8f8eb;hpb=879cd965ff9bf83ec7e5a191af566837bf5a3458;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..767a11d 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) 2021 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. @@ -20,26 +20,21 @@ // INTERNAL INCLUDES #include +#include +#include +#include #include #include -#include +#include #include -#include -#include -#include +#include namespace Dali { - 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 * @param program to set the matrices to @@ -49,161 +44,145 @@ static Matrix3 gNormalMatrix; ///< a shared matrix to calculate normal matrix, d * @param modelViewMatrix to set * @param modelViewProjectionMatrix to set */ -inline void SetMatrices( Program& program, - const Matrix& modelMatrix, - const Matrix& viewMatrix, - const Matrix& projectionMatrix, - const Matrix& modelViewMatrix ) -{ - GLint loc = program.GetUniformLocation( Program::UNIFORM_MODEL_MATRIX ); - if( Program::UNIFORM_UNKNOWN != loc ) +inline void SetMatrices(Program& program, + const Matrix& modelMatrix, + const Matrix& viewMatrix, + const Matrix& projectionMatrix, + const Matrix& modelViewMatrix) +{ + GLint loc = program.GetUniformLocation(Program::UNIFORM_MODEL_MATRIX); + if(Program::UNIFORM_UNKNOWN != loc) { - program.SetUniformMatrix4fv( loc, 1, modelMatrix.AsFloat() ); + program.SetUniformMatrix4fv(loc, 1, modelMatrix.AsFloat()); } - loc = program.GetUniformLocation( Program::UNIFORM_VIEW_MATRIX ); - if( Program::UNIFORM_UNKNOWN != loc ) + loc = program.GetUniformLocation(Program::UNIFORM_VIEW_MATRIX); + if(Program::UNIFORM_UNKNOWN != loc) { - if( program.GetViewMatrix() != &viewMatrix ) + if(program.GetViewMatrix() != &viewMatrix) { - program.SetViewMatrix( &viewMatrix ); - program.SetUniformMatrix4fv( loc, 1, viewMatrix.AsFloat() ); + program.SetViewMatrix(&viewMatrix); + program.SetUniformMatrix4fv(loc, 1, viewMatrix.AsFloat()); } } // set projection matrix if program has not yet received it this frame or if it is dirty - loc = program.GetUniformLocation( Program::UNIFORM_PROJECTION_MATRIX ); - if( Program::UNIFORM_UNKNOWN != loc ) + loc = program.GetUniformLocation(Program::UNIFORM_PROJECTION_MATRIX); + if(Program::UNIFORM_UNKNOWN != loc) { - if( program.GetProjectionMatrix() != &projectionMatrix ) + if(program.GetProjectionMatrix() != &projectionMatrix) { - program.SetProjectionMatrix( &projectionMatrix ); - program.SetUniformMatrix4fv( loc, 1, projectionMatrix.AsFloat() ); + program.SetProjectionMatrix(&projectionMatrix); + program.SetUniformMatrix4fv(loc, 1, projectionMatrix.AsFloat()); } } loc = program.GetUniformLocation(Program::UNIFORM_MODELVIEW_MATRIX); - if( Program::UNIFORM_UNKNOWN != loc ) + if(Program::UNIFORM_UNKNOWN != loc) { - program.SetUniformMatrix4fv( loc, 1, modelViewMatrix.AsFloat() ); + program.SetUniformMatrix4fv(loc, 1, modelViewMatrix.AsFloat()); } - loc = program.GetUniformLocation( Program::UNIFORM_MVP_MATRIX ); - if( Program::UNIFORM_UNKNOWN != loc ) + 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 ) + 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()); } } -} +} // namespace namespace Render { - -Renderer* Renderer::New( SceneGraph::RenderDataProvider* dataProvider, - Render::Geometry* geometry, - unsigned int blendingBitmask, - const Vector4* blendColor, - FaceCullingMode::Type faceCullingMode, - bool preMultipliedAlphaEnabled, - DepthWriteMode::Type depthWriteMode, - DepthTestMode::Type depthTestMode, - DepthFunction::Type depthFunction, - StencilParameters& stencilParameters ) -{ - return new Renderer( dataProvider, geometry, blendingBitmask, blendColor, - faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode, - depthFunction, stencilParameters ); -} - -Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider, - Render::Geometry* geometry, - unsigned int blendingBitmask, - const Vector4* blendColor, - FaceCullingMode::Type faceCullingMode, - bool preMultipliedAlphaEnabled, - DepthWriteMode::Type depthWriteMode, - DepthTestMode::Type depthTestMode, - DepthFunction::Type depthFunction, - StencilParameters& stencilParameters ) -: mRenderDataProvider( dataProvider ), - mContext( NULL), - mTextureCache( NULL ), - mGeometry( geometry ), +Renderer* Renderer::New(SceneGraph::RenderDataProvider* dataProvider, + Render::Geometry* geometry, + uint32_t blendingBitmask, + const Vector4& blendColor, + FaceCullingMode::Type faceCullingMode, + bool preMultipliedAlphaEnabled, + DepthWriteMode::Type depthWriteMode, + DepthTestMode::Type depthTestMode, + DepthFunction::Type depthFunction, + StencilParameters& stencilParameters) +{ + return new Renderer(dataProvider, geometry, blendingBitmask, blendColor, faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode, depthFunction, stencilParameters); +} + +Renderer::Renderer(SceneGraph::RenderDataProvider* dataProvider, + Render::Geometry* geometry, + uint32_t blendingBitmask, + const Vector4& blendColor, + FaceCullingMode::Type faceCullingMode, + bool preMultipliedAlphaEnabled, + DepthWriteMode::Type depthWriteMode, + DepthTestMode::Type depthTestMode, + DepthFunction::Type depthFunction, + StencilParameters& stencilParameters) +: mRenderDataProvider(dataProvider), + mContext(nullptr), + mGeometry(geometry), mUniformIndexMap(), mAttributesLocation(), - mStencilParameters( stencilParameters ), + mUniformsHash(), + mStencilParameters(stencilParameters), mBlendingOptions(), - mIndexedDrawFirstElement( 0 ), - mIndexedDrawElementsCount( 0 ), - mDepthFunction( depthFunction ), - mFaceCullingMode( faceCullingMode ), - mDepthWriteMode( depthWriteMode ), - mDepthTestMode( depthTestMode ), - mUpdateAttributesLocation( true ), - mPremultipledAlphaEnabled( preMultipliedAlphaEnabled ), - mBatchingEnabled( false ) -{ - if( blendingBitmask != 0u ) + mIndexedDrawFirstElement(0), + mIndexedDrawElementsCount(0), + mDepthFunction(depthFunction), + mFaceCullingMode(faceCullingMode), + mDepthWriteMode(depthWriteMode), + mDepthTestMode(depthTestMode), + mUpdateAttributesLocation(true), + mPremultipledAlphaEnabled(preMultipliedAlphaEnabled), + mShaderChanged(false), + mUpdated(true) +{ + if(blendingBitmask != 0u) { - mBlendingOptions.SetBitmask( blendingBitmask ); + mBlendingOptions.SetBitmask(blendingBitmask); } - if( blendColor ) - { - mBlendingOptions.SetBlendColor( *blendColor ); - } + mBlendingOptions.SetBlendColor(blendColor); } -void Renderer::Initialize( Context& context, SceneGraph::TextureCache& textureCache ) +void Renderer::Initialize(Context& context, Graphics::Controller& graphicsController) { - mContext = &context; - mTextureCache = &textureCache; + mContext = &context; + mGraphicsController = &graphicsController; } -Renderer::~Renderer() -{ -} +Renderer::~Renderer() = default; -void Renderer::SetRenderDataProvider( SceneGraph::RenderDataProvider* dataProvider ) +void Renderer::SetGeometry(Render::Geometry* geometry) { - mRenderDataProvider = dataProvider; + mGeometry = geometry; 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 ); - } } - -void Renderer::SetGeometry( Render::Geometry* geometry ) +void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size) { - mGeometry = geometry; - mUpdateAttributesLocation = true; + mDrawCommands.clear(); + mDrawCommands.insert(mDrawCommands.end(), pDrawCommands, pDrawCommands + size); } -void Renderer::SetBlending( Context& context, bool blend ) +void Renderer::SetBlending(Context& context, bool blend) { - context.SetBlend( blend ); - if( blend ) + context.SetBlend(blend); + if(blend) { // Blend color is optional and rarely used const Vector4* blendColor = mBlendingOptions.GetBlendColor(); - if( blendColor ) + if(blendColor) { - context.SetCustomBlendColor( *blendColor ); + context.SetCustomBlendColor(*blendColor); } else { @@ -211,15 +190,30 @@ void Renderer::SetBlending( Context& context, bool blend ) } // Set blend source & destination factors - context.BlendFuncSeparate( mBlendingOptions.GetBlendSrcFactorRgb(), - mBlendingOptions.GetBlendDestFactorRgb(), - mBlendingOptions.GetBlendSrcFactorAlpha(), - mBlendingOptions.GetBlendDestFactorAlpha() ); + context.BlendFuncSeparate(mBlendingOptions.GetBlendSrcFactorRgb(), + mBlendingOptions.GetBlendDestFactorRgb(), + mBlendingOptions.GetBlendSrcFactorAlpha(), + mBlendingOptions.GetBlendDestFactorAlpha()); // Set blend equations - context.BlendEquationSeparate( mBlendingOptions.GetBlendEquationRgb(), - mBlendingOptions.GetBlendEquationAlpha() ); + Dali::DevelBlendEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb(); + Dali::DevelBlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha(); + + if(mBlendingOptions.IsAdvancedBlendEquationApplied() && mPremultipledAlphaEnabled) + { + if(rgbEquation != alphaEquation) + { + DALI_LOG_ERROR("Advanced Blend Equation have to be appried by using BlendEquation.\n"); + } + context.BlendEquation(rgbEquation); + } + else + { + context.BlendEquationSeparate(rgbEquation, alphaEquation); + } } + + mUpdated = true; } void Renderer::GlContextDestroyed() @@ -231,128 +225,133 @@ void Renderer::GlCleanup() { } -void Renderer::SetUniforms( BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program ) +void Renderer::SetUniforms(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program) { // Check if the map has changed - DALI_ASSERT_DEBUG( mRenderDataProvider && "No Uniform map data provider available" ); + DALI_ASSERT_DEBUG(mRenderDataProvider && "No Uniform map data provider available"); const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap(); - if( uniformMapDataProvider.GetUniformMapChanged( bufferIndex ) || - node.GetUniformMapChanged(bufferIndex)) + if(uniformMapDataProvider.GetUniformMapChanged(bufferIndex) || + node.GetUniformMapChanged(bufferIndex) || + mUniformIndexMap.Count() == 0 || + mShaderChanged) { - const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex ); - const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap( bufferIndex ); + // Reset shader pointer + mShaderChanged = false; - unsigned int maxMaps = uniformMap.Count() + uniformMapNode.Count(); - mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size - mUniformIndexMap.Resize( maxMaps ); + const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap(bufferIndex); + const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap(bufferIndex); - unsigned int mapIndex(0); - for(; mapIndex < uniformMap.Count() ; ++mapIndex ) + 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); + + uint32_t mapIndex = 0; + for(; mapIndex < uniformMap.Count(); ++mapIndex) { - mUniformIndexMap[mapIndex].propertyValue = uniformMap[mapIndex]->propertyPtr; - mUniformIndexMap[mapIndex].uniformIndex = program.RegisterUniform( uniformMap[mapIndex]->uniformName ); + 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 ); - bool found(false); - for( unsigned int i(0); ipropertyPtr; - found = true; + mUniformIndexMap[i].propertyValue = uniformMapNode[nodeMapIndex].propertyPtr; + found = true; break; } } - if( !found ) + if(!found) { - mUniformIndexMap[mapIndex].propertyValue = uniformMapNode[nodeMapIndex]->propertyPtr; - mUniformIndexMap[mapIndex].uniformIndex = uniformIndex; + mUniformIndexMap[mapIndex].propertyValue = uniformMapNode[nodeMapIndex].propertyPtr; + mUniformIndexMap[mapIndex].uniformIndex = uniformIndex; ++mapIndex; } } - mUniformIndexMap.Resize( mapIndex ); + mUniformIndexMap.Resize(mapIndex); } // Set uniforms in local map - for( UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(), - end = mUniformIndexMap.End() ; - iter != end ; - ++iter ) + for(UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(), + end = mUniformIndexMap.End(); + iter != end; + ++iter) { - SetUniformFromProperty( bufferIndex, program, *iter ); + SetUniformFromProperty(bufferIndex, program, *iter); } - GLint sizeLoc = program.GetUniformLocation( Program::UNIFORM_SIZE ); - if( -1 != sizeLoc ) + GLint sizeLoc = program.GetUniformLocation(Program::UNIFORM_SIZE); + if(-1 != sizeLoc) { - program.SetSizeUniform3f( sizeLoc, size.x, size.y, size.z ); + program.SetSizeUniform3f(sizeLoc, size.x, size.y, size.z); } } -void Renderer::SetUniformFromProperty( BufferIndex bufferIndex, Program& program, UniformIndexMap& map ) +void Renderer::SetUniformFromProperty(BufferIndex bufferIndex, Program& program, UniformIndexMap& map) { GLint location = program.GetUniformLocation(map.uniformIndex); - if( Program::UNIFORM_UNKNOWN != location ) + if(Program::UNIFORM_UNKNOWN != location) { // switch based on property type to use correct GL uniform setter - switch ( map.propertyValue->GetType() ) + switch(map.propertyValue->GetType()) { case Property::INTEGER: { - program.SetUniform1i( location, map.propertyValue->GetInteger( bufferIndex ) ); + program.SetUniform1i(location, map.propertyValue->GetInteger(bufferIndex)); break; } case Property::FLOAT: { - program.SetUniform1f( location, map.propertyValue->GetFloat( bufferIndex ) ); + program.SetUniform1f(location, map.propertyValue->GetFloat(bufferIndex)); break; } case Property::VECTOR2: { - Vector2 value( map.propertyValue->GetVector2( bufferIndex ) ); - program.SetUniform2f( location, value.x, value.y ); + Vector2 value(map.propertyValue->GetVector2(bufferIndex)); + program.SetUniform2f(location, value.x, value.y); break; } case Property::VECTOR3: { - Vector3 value( map.propertyValue->GetVector3( bufferIndex ) ); - program.SetUniform3f( location, value.x, value.y, value.z ); + Vector3 value(map.propertyValue->GetVector3(bufferIndex)); + program.SetUniform3f(location, value.x, value.y, value.z); break; } case Property::VECTOR4: { - Vector4 value( map.propertyValue->GetVector4( bufferIndex ) ); - program.SetUniform4f( location, value.x, value.y, value.z, value.w ); + Vector4 value(map.propertyValue->GetVector4(bufferIndex)); + program.SetUniform4f(location, value.x, value.y, value.z, value.w); break; } case Property::ROTATION: { - Quaternion value( map.propertyValue->GetQuaternion( bufferIndex ) ); - program.SetUniform4f( location, value.mVector.x, value.mVector.y, value.mVector.z, value.mVector.w ); + Quaternion value(map.propertyValue->GetQuaternion(bufferIndex)); + program.SetUniform4f(location, value.mVector.x, value.mVector.y, value.mVector.z, value.mVector.w); break; } case Property::MATRIX: { const Matrix& value = map.propertyValue->GetMatrix(bufferIndex); - program.SetUniformMatrix4fv(location, 1, value.AsFloat() ); + program.SetUniformMatrix4fv(location, 1, value.AsFloat()); break; } case Property::MATRIX3: { const Matrix3& value = map.propertyValue->GetMatrix3(bufferIndex); - program.SetUniformMatrix3fv(location, 1, value.AsFloat() ); + program.SetUniformMatrix3fv(location, 1, value.AsFloat()); break; } @@ -365,68 +364,90 @@ void Renderer::SetUniformFromProperty( BufferIndex bufferIndex, Program& program } } -bool Renderer::BindTextures( Context& context, SceneGraph::TextureCache& textureCache, Program& program ) +bool Renderer::BindTextures(Context& context, Program& program, Graphics::CommandBuffer& commandBuffer, Vector& boundTextures) { - unsigned int textureUnit = 0; - bool result = true; + uint32_t textureUnit = 0; + bool result = true; + + GLint uniformLocation(-1); + std::vector& samplers(mRenderDataProvider->GetSamplers()); + std::vector& textures(mRenderDataProvider->GetTextures()); - GLint uniformLocation(-1); - std::vector& samplers( mRenderDataProvider->GetSamplers() ); - std::vector& newTextures( mRenderDataProvider->GetNewTextures() ); - for( size_t i(0); i textureBindings; + 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] ); - if( result && program.GetSamplerUniformLocation( i, uniformLocation ) ) + if(program.GetSamplerUniformLocation(i, uniformLocation)) { - program.SetUniform1i( uniformLocation, textureUnit ); + // if the sampler exists, + // if it's default, delete the graphics object + // otherwise re-initialize it if dirty + + const Graphics::Sampler* graphicsSampler = (samplers[i] ? samplers[i]->GetGraphicsObject() + : nullptr); + + boundTextures.PushBack(textures[i]->GetGraphicsObject()); + const Graphics::TextureBinding textureBinding{textures[i]->GetGraphicsObject(), graphicsSampler, textureUnit}; + textureBindings.push_back(textureBinding); + + program.SetUniform1i(uniformLocation, textureUnit); // Get through shader reflection ++textureUnit; } } } + commandBuffer.BindTextures(textureBindings); + return result; } -void Renderer::SetFaceCullingMode( FaceCullingMode::Type mode ) +void Renderer::SetFaceCullingMode(FaceCullingMode::Type mode) { - mFaceCullingMode = mode; + mFaceCullingMode = mode; + mUpdated = true; } -void Renderer::SetBlendingBitMask( unsigned int bitmask ) +void Renderer::SetBlendingBitMask(uint32_t bitmask) { - mBlendingOptions.SetBitmask( 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 ) +void Renderer::EnablePreMultipliedAlpha(bool enable) { mPremultipledAlphaEnabled = enable; + mUpdated = true; } -void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode ) +void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode) { mDepthWriteMode = depthWriteMode; + mUpdated = true; } -void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode ) +void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode) { mDepthTestMode = depthTestMode; + mUpdated = true; } DepthWriteMode::Type Renderer::GetDepthWriteMode() const @@ -439,9 +460,10 @@ DepthTestMode::Type Renderer::GetDepthTestMode() const return mDepthTestMode; } -void Renderer::SetDepthFunction( DepthFunction::Type depthFunction ) +void Renderer::SetDepthFunction(DepthFunction::Type depthFunction) { mDepthFunction = depthFunction; + mUpdated = true; } DepthFunction::Type Renderer::GetDepthFunction() const @@ -449,9 +471,10 @@ DepthFunction::Type Renderer::GetDepthFunction() const return mDepthFunction; } -void Renderer::SetRenderMode( RenderMode::Type renderMode ) +void Renderer::SetRenderMode(RenderMode::Type renderMode) { mStencilParameters.renderMode = renderMode; + mUpdated = true; } RenderMode::Type Renderer::GetRenderMode() const @@ -459,9 +482,10 @@ RenderMode::Type Renderer::GetRenderMode() const return mStencilParameters.renderMode; } -void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction ) +void Renderer::SetStencilFunction(StencilFunction::Type stencilFunction) { mStencilParameters.stencilFunction = stencilFunction; + mUpdated = true; } StencilFunction::Type Renderer::GetStencilFunction() const @@ -469,9 +493,10 @@ StencilFunction::Type Renderer::GetStencilFunction() const return mStencilParameters.stencilFunction; } -void Renderer::SetStencilFunctionMask( int stencilFunctionMask ) +void Renderer::SetStencilFunctionMask(int stencilFunctionMask) { mStencilParameters.stencilFunctionMask = stencilFunctionMask; + mUpdated = true; } int Renderer::GetStencilFunctionMask() const @@ -479,9 +504,10 @@ int Renderer::GetStencilFunctionMask() const return mStencilParameters.stencilFunctionMask; } -void Renderer::SetStencilFunctionReference( int stencilFunctionReference ) +void Renderer::SetStencilFunctionReference(int stencilFunctionReference) { mStencilParameters.stencilFunctionReference = stencilFunctionReference; + mUpdated = true; } int Renderer::GetStencilFunctionReference() const @@ -489,9 +515,10 @@ int Renderer::GetStencilFunctionReference() const return mStencilParameters.stencilFunctionReference; } -void Renderer::SetStencilMask( int stencilMask ) +void Renderer::SetStencilMask(int stencilMask) { mStencilParameters.stencilMask = stencilMask; + mUpdated = true; } int Renderer::GetStencilMask() const @@ -499,9 +526,10 @@ int Renderer::GetStencilMask() const return mStencilParameters.stencilMask; } -void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail ) +void Renderer::SetStencilOperationOnFail(StencilOperation::Type stencilOperationOnFail) { mStencilParameters.stencilOperationOnFail = stencilOperationOnFail; + mUpdated = true; } StencilOperation::Type Renderer::GetStencilOperationOnFail() const @@ -509,9 +537,10 @@ StencilOperation::Type Renderer::GetStencilOperationOnFail() const return mStencilParameters.stencilOperationOnFail; } -void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail ) +void Renderer::SetStencilOperationOnZFail(StencilOperation::Type stencilOperationOnZFail) { mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail; + mUpdated = true; } StencilOperation::Type Renderer::GetStencilOperationOnZFail() const @@ -519,9 +548,10 @@ StencilOperation::Type Renderer::GetStencilOperationOnZFail() const return mStencilParameters.stencilOperationOnZFail; } -void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass ) +void Renderer::SetStencilOperationOnZPass(StencilOperation::Type stencilOperationOnZPass) { mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass; + mUpdated = true; } StencilOperation::Type Renderer::GetStencilOperationOnZPass() const @@ -529,90 +559,215 @@ StencilOperation::Type Renderer::GetStencilOperationOnZPass() const return mStencilParameters.stencilOperationOnZPass; } -void Renderer::SetBatchingEnabled( bool batchingEnabled ) +void Renderer::Upload() { - mBatchingEnabled = batchingEnabled; + mGeometry->Upload(*mGraphicsController); } -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 ) +void Renderer::Render(Context& context, + BufferIndex bufferIndex, + const SceneGraph::NodeDataProvider& node, + const Matrix& modelMatrix, + const Matrix& modelViewMatrix, + const Matrix& viewMatrix, + const Matrix& projectionMatrix, + const Vector3& size, + bool blend, + Vector& boundTextures, + const Dali::Internal::SceneGraph::RenderInstruction& instruction, + uint32_t queueIndex) { - // Get the program to use: - Program* program = mRenderDataProvider->GetShader().GetProgram(); - if( !program ) + // 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 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 ) + if(cmd.queue == queueIndex) { - DALI_LOG_ERROR( "Failed to get program for shader at address %p.\n", (void*)&mRenderDataProvider->GetShader() ); - return; + commands.emplace_back(&cmd); } } - //Set cull face mode - context.CullFace( mFaceCullingMode ); + // Have commands but nothing to be drawn - abort + if(!mDrawCommands.empty() && commands.empty()) + { + return; + } - //Set blending mode - SetBlending( context, blend ); + // Get the program to use: + Program* program = mRenderDataProvider->GetShader().GetProgram(); + if(!program) + { + DALI_LOG_ERROR("Failed to get program for shader at address %p.\n", reinterpret_cast(&mRenderDataProvider->GetShader())); + return; + } + + // For now, create command buffer to perform only the texture / sample binding + // and submit it. + // Expect this call to glBindTextureForUnit, and glTexParameteri() for the sampler + Graphics::UniquePtr commandBuffer = mGraphicsController->CreateCommandBuffer( + Graphics::CommandBufferCreateInfo() + .SetLevel(Graphics::CommandBufferLevel::SECONDARY), + nullptr); + + //Set cull face mode + 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, *commandBuffer.get(), boundTextures))) { // Only set up and draw if we have textures and they are all valid // set projection and view matrix if program has not yet received them yet this frame - SetMatrices( *program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix ); + SetMatrices(*program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix); // set color uniform - GLint loc = program->GetUniformLocation( Program::UNIFORM_COLOR ); - if( Program::UNIFORM_UNKNOWN != loc ) + GLint loc = program->GetUniformLocation(Program::UNIFORM_COLOR); + if(Program::UNIFORM_UNKNOWN != loc) { - const Vector4& color = node.GetRenderColor( bufferIndex ); - if( mPremultipledAlphaEnabled ) + 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; + SetUniforms(bufferIndex, node, size, *program); - 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(mBlendingOptions.IsAdvancedBlendEquationApplied() && mPremultipledAlphaEnabled) + { + context.BlendBarrier(); + } + + if(mDrawCommands.empty()) + { + SetBlending(context, blend); + + mGeometry->Draw(context, + *mGraphicsController, + *commandBuffer.get(), + 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, *mGraphicsController, *commandBuffer.get(), bufferIndex, mAttributesLocation, cmd->firstIndex, cmd->elementCount); + } + } + } + mUpdated = false; } } -void Renderer::SetSortAttributes( BufferIndex bufferIndex, - SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes ) const +void Renderer::SetSortAttributes(BufferIndex bufferIndex, + SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes) const { - sortAttributes.shader = &( mRenderDataProvider->GetShader() ); + sortAttributes.shader = &(mRenderDataProvider->GetShader()); sortAttributes.geometry = mGeometry; } -} // namespace SceneGraph +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 Render } // namespace Internal