X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Frenderers%2Frender-renderer.cpp;h=cbad8bb8ebd4b4c362ee1424d842b5030c40b4fc;hb=2b10280985738c74efa2aa0fb956a837c69acee6;hp=20e9fd1165a949e0e10553b26b2f14dc78311767;hpb=4d28f18770c0f1f58fb401817540ea7abb7487b3;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 20e9fd1..cbad8bb 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,15 +18,17 @@ // CLASS HEADER #include - // INTERNAL INCLUDES +#include #include +#include #include #include #include +#include +#include #include -#include -#include +#include namespace Dali { @@ -107,6 +109,64 @@ inline void SetMatrices( Program& program, 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, + bool writeToColorBuffer ) +{ + return new Renderer( dataProvider, geometry, blendingBitmask, blendColor, + faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode, + depthFunction, stencilParameters, writeToColorBuffer ); +} + +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, + bool writeToColorBuffer ) +: mRenderDataProvider( dataProvider ), + mContext( NULL), + mTextureCache( NULL ), + mUniformNameCache( NULL ), + mGeometry( geometry ), + mUniformIndexMap(), + mAttributesLocation(), + mStencilParameters( stencilParameters ), + mBlendingOptions(), + mIndexedDrawFirstElement( 0 ), + mIndexedDrawElementsCount( 0 ), + mDepthFunction( depthFunction ), + mFaceCullingMode( faceCullingMode ), + mDepthWriteMode( depthWriteMode ), + mDepthTestMode( depthTestMode ), + mWriteToColorBuffer( writeToColorBuffer ), + mUpdateAttributesLocation( true ), + mPremultipledAlphaEnabled( preMultipliedAlphaEnabled ) +{ + if( blendingBitmask != 0u ) + { + mBlendingOptions.SetBitmask( blendingBitmask ); + } + + if( blendColor ) + { + mBlendingOptions.SetBlendColor( *blendColor ); + } +} + void Renderer::Initialize( Context& context, SceneGraph::TextureCache& textureCache, Render::UniformNameCache& uniformNameCache ) { mContext = &context; @@ -118,128 +178,483 @@ Renderer::~Renderer() { } -void Renderer::SetShader( SceneGraph::Shader* shader ) +void Renderer::SetRenderDataProvider( SceneGraph::RenderDataProvider* dataProvider ) +{ + mRenderDataProvider = dataProvider; + mUpdateAttributesLocation = true; +} + +void Renderer::SetGeometry( Render::Geometry* geometry ) { - mShader = shader; + mGeometry = geometry; + mUpdateAttributesLocation = true; +} + +void Renderer::SetBlending( Context& context, bool blend ) +{ + context.SetBlend( blend ); + if( blend ) + { + // Blend color is optional and rarely used + const Vector4* blendColor = mBlendingOptions.GetBlendColor(); + if( blendColor ) + { + context.SetCustomBlendColor( *blendColor ); + } + else + { + context.SetDefaultBlendColor(); + } + + // Set blend source & destination factors + context.BlendFuncSeparate( mBlendingOptions.GetBlendSrcFactorRgb(), + mBlendingOptions.GetBlendDestFactorRgb(), + mBlendingOptions.GetBlendSrcFactorAlpha(), + mBlendingOptions.GetBlendDestFactorAlpha() ); + + // Set blend equations + context.BlendEquationSeparate( mBlendingOptions.GetBlendEquationRgb(), + mBlendingOptions.GetBlendEquationAlpha() ); + } } -void Renderer::SetCullFace( Dali::Material::FaceCullingMode mode ) +void Renderer::GlContextDestroyed() { - DALI_ASSERT_DEBUG( mode >= Dali::Material::NONE && mode <= Dali::Material::CULL_BACK_AND_FRONT ); - mCullFaceMode = mode; + mGeometry->GlContextDestroyed(); } -void Renderer::SetSampler( unsigned int samplerBitfield ) +void Renderer::GlCleanup() { - mSamplerBitfield = samplerBitfield; } -void Renderer::Render( Context& context, - SceneGraph::TextureCache& textureCache, - BufferIndex bufferIndex, - const SceneGraph::NodeDataProvider& node, - SceneGraph::Shader& defaultShader, - const Matrix& modelViewMatrix, - const Matrix& viewMatrix, - const Matrix& projectionMatrix, - bool cull, - bool blend ) +void Renderer::SetUniforms( BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program ) { - NewRenderer* renderer = GetNewRenderer(); // avoid a dynamic cast per item per frame + // Check if the map has changed + DALI_ASSERT_DEBUG( mRenderDataProvider && "No Uniform map data provider available" ); - if( renderer ) + const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap(); + + if( uniformMapDataProvider.GetUniformMapChanged( bufferIndex ) || + node.GetUniformMapChanged(bufferIndex)) { - // Get the shader from the material: - mShader = &renderer->mRenderDataProvider->GetShader(); + const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex ); + const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap( bufferIndex ); + + unsigned int maxMaps = uniformMap.Count() + uniformMapNode.Count(); + mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size + mUniformIndexMap.Resize( maxMaps ); + + unsigned int 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 ) + { + unsigned int uniformIndex = program.RegisterUniform( uniformMapNode[nodeMapIndex]->uniformName ); + bool found(false); + for( unsigned int i(0); ipropertyPtr; + found = true; + break; + } + } + + if( !found ) + { + mUniformIndexMap[mapIndex].propertyValue = uniformMapNode[nodeMapIndex]->propertyPtr; + mUniformIndexMap[mapIndex].uniformIndex = uniformIndex; + ++mapIndex; + } + } + + mUniformIndexMap.Resize( mapIndex ); } - // if mShader is NULL it means we're set to default - if( !mShader ) + // Set uniforms in local map + for( UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(), + end = mUniformIndexMap.End() ; + iter != end ; + ++iter ) { - mShader = &defaultShader; + SetUniformFromProperty( bufferIndex, program, *iter ); } - if( !CheckResources() ) + GLint sizeLoc = program.GetUniformLocation( Program::UNIFORM_SIZE ); + if( -1 != sizeLoc ) { - // CheckResources() is overriden in derived classes. - // Prevents modify the GL state if resources are not ready and nothing is to be rendered. - return; + program.SetSizeUniform3f( sizeLoc, size.x, size.y, size.z ); } +} - // Get the program to use: - Program* program = mShader->GetProgram(); - if( !program ) +void Renderer::SetUniformFromProperty( BufferIndex bufferIndex, Program& program, UniformIndexMap& map ) +{ + GLint location = program.GetUniformLocation(map.uniformIndex); + if( Program::UNIFORM_UNKNOWN != location ) { - // 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 ) + // switch based on property type to use correct GL uniform setter + switch ( map.propertyValue->GetType() ) { - DALI_LOG_ERROR( "Failed to get program for shader at address %p.", (void*) &*mShader ); - return; + case Property::INTEGER: + { + program.SetUniform1i( location, map.propertyValue->GetInteger( bufferIndex ) ); + break; + } + case Property::FLOAT: + { + program.SetUniform1f( location, map.propertyValue->GetFloat( bufferIndex ) ); + break; + } + case Property::VECTOR2: + { + 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 ); + break; + } + + case Property::VECTOR4: + { + 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 ); + break; + } + + case Property::MATRIX: + { + const Matrix& value = map.propertyValue->GetMatrix(bufferIndex); + program.SetUniformMatrix4fv(location, 1, value.AsFloat() ); + break; + } + + case Property::MATRIX3: + { + const Matrix3& value = map.propertyValue->GetMatrix3(bufferIndex); + program.SetUniformMatrix3fv(location, 1, value.AsFloat() ); + break; + } + + default: + { + // Other property types are ignored + break; + } } } +} - // Take the program into use so we can send uniforms to it - program->Use(); +bool Renderer::BindTextures( Context& context, SceneGraph::TextureCache& textureCache, Program& program ) +{ + unsigned int textureUnit = 0; + bool result = true; - DoSetCullFaceMode( context ); + std::vector& samplers( mRenderDataProvider->GetSamplers() ); - // Enable/disable blending - context.SetBlend( blend ); - if( blend ) + std::vector& textures( mRenderDataProvider->GetTextures() ); + GLint uniformLocation(-1); + for( size_t i(0); result && imBitfield; + } + + texture->ApplySampler( (TextureUnit)textureUnit, samplerBitfield ); + + ++textureUnit; + } + } + } } - // Ignore missing uniforms - custom shaders and flat color shaders don't have SAMPLER - // set projection and view matrix if program has not yet received them yet this frame - const Matrix& modelMatrix = node.GetModelMatrix( bufferIndex ); - SetMatrices( *program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix ); - - // set color uniform - GLint loc = program->GetUniformLocation( Program::UNIFORM_COLOR ); - if( Program::UNIFORM_UNKNOWN != loc ) + std::vector& newTextures( mRenderDataProvider->GetNewTextures() ); + for( size_t i(0); result && iSetUniform4f( loc, color.r, color.g, color.b, color.a ); + if( newTextures[i] ) + { + result = program.GetSamplerUniformLocation( i, uniformLocation ) && + newTextures[i]->Bind(context, textureUnit, samplers[i] ); + + if( result ) + { + program.SetUniform1i( uniformLocation, textureUnit ); + ++textureUnit; + } + } } - //@todo MESH_REWORK Remove after removing ImageRenderer - DoSetUniforms(context, bufferIndex, mShader, program ); + return result; +} - // subclass rendering and actual draw call - DoRender( context, textureCache, node, bufferIndex, *program, modelViewMatrix, viewMatrix ); +void Renderer::SetFaceCullingMode( FaceCullingMode::Type mode ) +{ + mFaceCullingMode = mode; } -void Renderer::SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RendererWithSortAttributes& sortAttributes ) const +void Renderer::SetBlendingBitMask( unsigned int bitmask ) { - sortAttributes.shader = mShader; - sortAttributes.textureResourceId = Integration::InvalidResourceId; - sortAttributes.geometry = NULL; + mBlendingOptions.SetBitmask( bitmask ); } -// can be overridden by deriving class -void Renderer::DoSetUniforms(Context& context, BufferIndex bufferIndex, SceneGraph::Shader* shader, Program* program ) +void Renderer::SetBlendColor( const Vector4* color ) { - shader->SetUniforms( context, *program, bufferIndex ); + mBlendingOptions.SetBlendColor( *color ); } -// can be overridden by deriving class -void Renderer::DoSetCullFaceMode( Context& context ) +void Renderer::SetIndexedDrawFirstElement( size_t firstElement ) { - // Set face culling mode - context.CullFace( mCullFaceMode ); + mIndexedDrawFirstElement = firstElement; } -Renderer::Renderer() -: mContext(NULL), - mTextureCache( NULL ), - mUniformNameCache( NULL ), - mShader( NULL ), - mSamplerBitfield( ImageSampler::PackBitfield( FilterMode::DEFAULT, FilterMode::DEFAULT ) ), - mCullFaceMode( Dali::Material::NONE ) +void Renderer::SetIndexedDrawElementsCount( size_t elementsCount ) +{ + mIndexedDrawElementsCount = elementsCount; +} + +void Renderer::EnablePreMultipliedAlpha( bool enable ) +{ + mPremultipledAlphaEnabled = enable; +} + +void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode ) +{ + mDepthWriteMode = depthWriteMode; +} + +void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode ) +{ + mDepthTestMode = depthTestMode; +} + +DepthWriteMode::Type Renderer::GetDepthWriteMode() const +{ + return mDepthWriteMode; +} + +DepthTestMode::Type Renderer::GetDepthTestMode() const +{ + return mDepthTestMode; +} + +void Renderer::SetDepthFunction( DepthFunction::Type depthFunction ) +{ + mDepthFunction = depthFunction; +} + +DepthFunction::Type Renderer::GetDepthFunction() const +{ + return mDepthFunction; +} + +void Renderer::SetStencilMode( StencilMode::Type stencilMode ) { + mStencilParameters.stencilMode = stencilMode; +} + +StencilMode::Type Renderer::GetStencilMode() const +{ + return mStencilParameters.stencilMode; +} + +void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction ) +{ + mStencilParameters.stencilFunction = stencilFunction; +} + +StencilFunction::Type Renderer::GetStencilFunction() const +{ + return mStencilParameters.stencilFunction; +} + +void Renderer::SetStencilFunctionMask( int stencilFunctionMask ) +{ + mStencilParameters.stencilFunctionMask = stencilFunctionMask; +} + +int Renderer::GetStencilFunctionMask() const +{ + return mStencilParameters.stencilFunctionMask; +} + +void Renderer::SetStencilFunctionReference( int stencilFunctionReference ) +{ + mStencilParameters.stencilFunctionReference = stencilFunctionReference; +} + +int Renderer::GetStencilFunctionReference() const +{ + return mStencilParameters.stencilFunctionReference; +} + +void Renderer::SetStencilMask( int stencilMask ) +{ + mStencilParameters.stencilMask = stencilMask; +} + +int Renderer::GetStencilMask() const +{ + return mStencilParameters.stencilMask; +} + +void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail ) +{ + mStencilParameters.stencilOperationOnFail = stencilOperationOnFail; +} + +StencilOperation::Type Renderer::GetStencilOperationOnFail() const +{ + return mStencilParameters.stencilOperationOnFail; +} + +void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail ) +{ + mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail; +} + +StencilOperation::Type Renderer::GetStencilOperationOnZFail() const +{ + return mStencilParameters.stencilOperationOnZFail; +} + +void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass ) +{ + mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass; +} + +StencilOperation::Type Renderer::GetStencilOperationOnZPass() const +{ + return mStencilParameters.stencilOperationOnZPass; +} + +void Renderer::SetWriteToColorBuffer( bool writeToColorBuffer ) +{ + mWriteToColorBuffer = writeToColorBuffer; +} + +bool Renderer::GetWriteToColorBuffer() const +{ + return mWriteToColorBuffer; +} + +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, + bool blend ) +{ + // 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; + } + } + + //Set cull face mode + context.CullFace( mFaceCullingMode ); + + //Set blending mode + SetBlending( context, blend ); + + // Take the program into use so we can send uniforms to it + program->Use(); + + if( DALI_LIKELY( BindTextures( context, textureCache, *program ) ) ) + { + // 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 ); + + // set color uniform + GLint loc = program->GetUniformLocation( Program::UNIFORM_COLOR ); + if( Program::UNIFORM_UNKNOWN != loc ) + { + 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 ); + } + else + { + program->SetUniform4f( loc, color.r, color.g, color.b, color.a ); + } + } + + SetUniforms( bufferIndex, node, size, *program ); + + if( mUpdateAttributesLocation || mGeometry->AttributesChanged() ) + { + mGeometry->GetAttributeLocationFromProgram( mAttributesLocation, *program, bufferIndex ); + mUpdateAttributesLocation = false; + } + + mGeometry->UploadAndDraw( context, bufferIndex, mAttributesLocation, mIndexedDrawFirstElement, mIndexedDrawElementsCount ); + } +} + +void Renderer::SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RendererWithSortAttributes& sortAttributes ) const +{ + sortAttributes.shader = &( mRenderDataProvider->GetShader() ); + const std::vector& textures( mRenderDataProvider->GetTextures() ); + if( !textures.empty() ) + { + sortAttributes.textureResourceId = textures[0].GetTextureId(); + } + else + { + sortAttributes.textureResourceId = Integration::InvalidResourceId; + } + + sortAttributes.geometry = mGeometry; } } // namespace SceneGraph