From: adam.b Date: Thu, 2 Jan 2020 16:45:08 +0000 (+0000) Subject: [Tizen] Regenerating uniform maps fix X-Git-Tag: accepted/tizen/5.5/unified/20200128.122305~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;ds=sidebyside;h=baef81c81217e013c1cc253ac636f154c7e61370;p=platform%2Fcore%2Fuifw%2Fdali-core.git [Tizen] Regenerating uniform maps fix The problem: Crash when uniform maps changed on the update side but not on the render side. The crash is caused if "keep rendering". The fix: When new shader is set, the message is sent to Render::Renderer which will be executed when object becomes visible (renderable). The message sets the flag indicating whether the shader changed so next time the renderer sets uniforms first the maps will be regenerated. Change-Id: I06d872945f1db6c8fe180d347a5674e8931761b7 --- diff --git a/automated-tests/src/dali/utc-Dali-Renderer.cpp b/automated-tests/src/dali/utc-Dali-Renderer.cpp index 0410a52..3a12e96 100644 --- a/automated-tests/src/dali/utc-Dali-Renderer.cpp +++ b/automated-tests/src/dali/utc-Dali-Renderer.cpp @@ -3009,3 +3009,51 @@ int UtcDaliRendererRenderingBehavior(void) END_TEST; } + +int UtcDaliRendererRegenerateUniformMap(void) +{ + TestApplication application; + + tet_infoline( "Test regenerating uniform map when attaching renderer to the node" ); + + Geometry geometry = CreateQuadGeometry(); + Shader shader = Shader::New( "vertexSrc", "fragmentSrc" ); + Renderer renderer = Renderer::New( geometry, shader ); + + Actor actor = Actor::New(); + actor.AddRenderer( renderer ); + actor.SetSize( 400, 400 ); + actor.SetColor( Vector4( 1.0f, 0.0f, 1.0f, 1.0f ) ); + Stage::GetCurrent().Add( actor ); + + application.SendNotification(); + application.Render(); + + actor.RemoveRenderer( renderer ); + shader = Shader::New( "vertexSrc", "fragmentSrc" ); + shader.RegisterProperty( "opacity", 0.5f ); + renderer.SetShader( shader ); + + Stage::GetCurrent().KeepRendering( 1.0f ); + + // Update for several frames + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + + // Add Renderer + actor.AddRenderer( renderer ); + application.SendNotification(); + application.Render(); + + // Nothing to test here, the test must not crash + auto updateStatus = application.GetUpdateStatus(); + DALI_TEST_CHECK( updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING ); + + END_TEST; +} diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 74c4959..9324d86 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -145,7 +145,8 @@ Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider, mDepthWriteMode( depthWriteMode ), mDepthTestMode( depthTestMode ), mUpdateAttributesLocation( true ), - mPremultipledAlphaEnabled( preMultipliedAlphaEnabled ) + mPremultipledAlphaEnabled( preMultipliedAlphaEnabled ), + mShaderChanged( false ) { if( blendingBitmask != 0u ) { @@ -216,8 +217,12 @@ void Renderer::SetUniforms( BufferIndex bufferIndex, const SceneGraph::NodeDataP if( uniformMapDataProvider.GetUniformMapChanged( bufferIndex ) || node.GetUniformMapChanged(bufferIndex) || - mUniformIndexMap.Count() == 0) + mUniformIndexMap.Count() == 0 || + mShaderChanged ) { + // Reset shader pointer + mShaderChanged = false; + const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex ); const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap( bufferIndex ); @@ -586,6 +591,11 @@ void Renderer::SetSortAttributes( BufferIndex bufferIndex, sortAttributes.geometry = mGeometry; } +void Renderer::SetShaderChanged( bool value ) +{ + mShaderChanged = value; +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index 9157d72..406dff4 100755 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -371,6 +371,13 @@ public: */ void SetSortAttributes( BufferIndex bufferIndex, SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes ) const; + /** + * Sets the flag indicating whether shader changed. + * + * @param[in] value True if shader changed + */ + void SetShaderChanged( bool value ); + private: struct UniformIndexMap; @@ -444,6 +451,8 @@ private: DepthTestMode::Type mDepthTestMode:3; ///< The depth test mode bool mUpdateAttributesLocation:1; ///< Indicates attribute locations have changed bool mPremultipledAlphaEnabled:1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required + bool mShaderChanged:1; ///< Flag indicating the shader changed and uniform maps have to be updated + }; diff --git a/dali/internal/update/rendering/scene-graph-renderer.cpp b/dali/internal/update/rendering/scene-graph-renderer.cpp index b7180cb..6ce9e50 100755 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -112,7 +112,8 @@ enum Flags 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_WRITE_TO_COLOR_BUFFER = 1 << 18, + RESEND_SHADER = 1 << 19, }; } // Anonymous namespace @@ -345,6 +346,13 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex ) new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass ); } + if( mResendFlag & RESEND_SHADER ) + { + typedef MessageValue1< Render::Renderer, bool > DerivedType; + uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + new (slot) DerivedType( mRenderer, &Render::Renderer::SetShaderChanged, true ); + } + mResendFlag = 0; } } @@ -377,7 +385,7 @@ void Renderer::SetShader( Shader* shader ) mShader = shader; mShader->AddConnectionObserver( *this ); mRegenerateUniformMap = REGENERATE_UNIFORM_MAP; - mResendFlag |= RESEND_GEOMETRY; + mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER; if( mRenderDataProvider ) { diff --git a/dali/internal/update/rendering/scene-graph-renderer.h b/dali/internal/update/rendering/scene-graph-renderer.h index 3dda873..a959f49 100755 --- a/dali/internal/update/rendering/scene-graph-renderer.h +++ b/dali/internal/update/rendering/scene-graph-renderer.h @@ -482,7 +482,6 @@ private: DepthWriteMode::Type mDepthWriteMode:3; ///< Local copy of the depth write mode DepthTestMode::Type mDepthTestMode:3; ///< Local copy of the depth test mode DevelRenderer::Rendering::Type mRenderingBehavior:2; ///< The rendering behavior - bool mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame bool mPremultipledAlphaEnabled:1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required bool mDirty:1; ///< Required for marking it dirty in case of partial update.