From b7f9589bbc2571acb0c08d710a18b1038fe76083 Mon Sep 17 00:00:00 2001 From: Chu Hoang Date: Mon, 20 Jul 2015 09:20:26 +0100 Subject: [PATCH 1/1] Changed RendererAttachment to use blend flag from RenderDataProvider rather than base class's mUseBlend flag. This fixes a issue where (when adding to the stage, removing and then re-adding) the Renderer blend flag can be become out of sync with the RenderableAttachment's mUseBlend flag. Related: moved Renderer::mUseBlend flag and relevant methods to ImageRender since this way of controlling the blending is now specific to ImageRenderer. Change-Id: Iebc0664946fe4c83b43291aa8004c66e004cbf22 --- .../render/data-providers/render-data-provider.cpp | 12 +++++- .../render/data-providers/render-data-provider.h | 14 +++++++ dali/internal/render/renderers/render-renderer.cpp | 6 +-- dali/internal/render/renderers/render-renderer.h | 2 + .../renderers/scene-graph-image-renderer.cpp | 44 +++++++++++++++++++++ .../render/renderers/scene-graph-image-renderer.h | 26 +++++++++++++ .../render/renderers/scene-graph-renderer.cpp | 45 ---------------------- .../render/renderers/scene-graph-renderer.h | 22 +---------- .../update/manager/prepare-render-algorithms.cpp | 2 +- .../scene-graph-image-attachment.cpp | 27 ++++++++++--- .../scene-graph-image-attachment.h | 1 + .../scene-graph-renderable-attachment.cpp | 25 ------------ .../scene-graph-renderable-attachment.h | 12 ++---- .../scene-graph-renderer-attachment.cpp | 9 +++++ .../scene-graph-renderer-attachment.h | 2 +- 15 files changed, 138 insertions(+), 111 deletions(-) diff --git a/dali/internal/render/data-providers/render-data-provider.cpp b/dali/internal/render/data-providers/render-data-provider.cpp index f78af39..d4b031b 100644 --- a/dali/internal/render/data-providers/render-data-provider.cpp +++ b/dali/internal/render/data-providers/render-data-provider.cpp @@ -27,7 +27,8 @@ namespace SceneGraph RenderDataProvider::RenderDataProvider() : mMaterialDataProvider( NULL ), mUniformMapDataProvider( NULL ), - mShader( NULL ) + mShader( NULL ), + mUseBlend( false ) { } @@ -75,6 +76,15 @@ const RenderDataProvider::Samplers& RenderDataProvider::GetSamplers() const return mSamplers; } +void RenderDataProvider::SetUseBlend( bool useBlend ) +{ + mUseBlend = useBlend; +} + +bool RenderDataProvider::GetUseBlend( BufferIndex bufferIndex ) const +{ + return mUseBlend; +} } // SceneGraph } // Internal diff --git a/dali/internal/render/data-providers/render-data-provider.h b/dali/internal/render/data-providers/render-data-provider.h index cf3aeb6..fc15eb8 100644 --- a/dali/internal/render/data-providers/render-data-provider.h +++ b/dali/internal/render/data-providers/render-data-provider.h @@ -110,11 +110,25 @@ public: */ const Samplers& GetSamplers() const; + /** + * Set the use blend flag to decide if the renderer will perform blending + * @param[in] useBlend The flag to decide if the renderer will perform blending + */ + void SetUseBlend( bool useBlend ); + + /** + * Get the use blend flag that decides if the renderer will perform blending + * @param[in] buffer index + * @return The use blend flag that decides if the renderer will perform blending + */ + bool GetUseBlend( BufferIndex bufferIndex ) const; + private: const MaterialDataProvider* mMaterialDataProvider; const UniformMapDataProvider* mUniformMapDataProvider; Shader* mShader; Samplers mSamplers; + bool mUseBlend; // Give RendererAttachment access to our private data to reduce copying vectors on construction. friend class RendererAttachment; diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 5783f3e..f8a4c9e 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -100,9 +100,9 @@ void NewRenderer::DoSetCullFaceMode( Context& context, BufferIndex bufferIndex ) void NewRenderer::DoSetBlending( Context& context, BufferIndex bufferIndex ) { - context.SetBlend(mUseBlend); // @todo MESH_REWORK Should use a RendererDataProvider - - if( mUseBlend ) + bool blend = mRenderDataProvider->GetUseBlend( bufferIndex ); + context.SetBlend( blend ); + if( blend ) { const MaterialDataProvider& material = mRenderDataProvider->GetMaterial(); diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index 4756ea0..2a3ee8c 100644 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -220,6 +220,8 @@ private: Vector mAttributesLocation; bool mUpdateAttributesLocation; + + bool mUseBlend:1; ///< True if blending should be enabled, 1 bit is enough }; diff --git a/dali/internal/render/renderers/scene-graph-image-renderer.cpp b/dali/internal/render/renderers/scene-graph-image-renderer.cpp index b4f8390..dfba719 100644 --- a/dali/internal/render/renderers/scene-graph-image-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-image-renderer.cpp @@ -159,6 +159,21 @@ void ImageRenderer::SetNinePatchBorder( const Vector4& border, bool inPixels ) mIsMeshGenerated = false; } +void ImageRenderer::SetUseBlend( bool useBlend ) +{ + mUseBlend = useBlend; +} + +void ImageRenderer::SetBlendingOptions( unsigned int options ) +{ + mBlendingOptions.SetBitmask( options ); +} + +void ImageRenderer::SetBlendColor( const Vector4& color ) +{ + mBlendingOptions.SetBlendColor( color ); +} + void ImageRenderer::CalculateMeshData( MeshType type, const Vector2& targetSize, bool usePixelArea ) { mMeshType = type; @@ -351,6 +366,34 @@ void ImageRenderer::DoRender( Context& context, TextureCache& textureCache, Buff } } +void ImageRenderer::DoSetBlending(Context& context, BufferIndex bufferIndex ) +{ + // Enables/disables blending mode. + context.SetBlend( mUseBlend ); + + // Set the blend color + const Vector4* const customColor = mBlendingOptions.GetBlendColor(); + if( customColor ) + { + context.SetCustomBlendColor( *customColor ); + } + 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 ImageRenderer::UpdateVertexBuffer( Context& context, GLsizeiptr size, const GLvoid *data ) { // create/destroy if needed/not needed. @@ -927,6 +970,7 @@ ImageRenderer::ImageRenderer( NodeDataProvider& dataProvider ) mMeshType( ImageRenderer::QUAD ), mIsMeshGenerated( false ), mBorderInPixels( false ), + mUseBlend( false ), mUsePixelArea( false ) { } diff --git a/dali/internal/render/renderers/scene-graph-image-renderer.h b/dali/internal/render/renderers/scene-graph-image-renderer.h index 226501b..7bfc858 100644 --- a/dali/internal/render/renderers/scene-graph-image-renderer.h +++ b/dali/internal/render/renderers/scene-graph-image-renderer.h @@ -88,6 +88,24 @@ public: void SetNinePatchBorder( const Vector4& border, bool inPixels ); /** + * Set whether the ImageRenderer should use blending + * @param[in] useBlend True if blending should be used. + */ + void SetUseBlend( bool useBlend ); + + /** + * Set the blending options. + * @param[in] options A bitmask of blending options. + */ + void SetBlendingOptions( unsigned int options ); + + /** + * Set the blend color. + * @param[in] color The new blend-color. + */ + void SetBlendColor( const Vector4& color ); + + /** * Calculate the mesh data used by the ImageRenderer. * @param[in] type The type of mesh data required; either quad, nine-patch or grid. * @param[in] targetSize The size which the mesh data should fit inside. @@ -125,6 +143,11 @@ public: */ virtual void DoRender( Context& context, TextureCache& textureCache, BufferIndex bufferIndex, Program& program, const Matrix& modelViewMatrix, const Matrix& viewMatrix ); + /** + * @copydoc Dali::Internal::SceneGraph::Renderer::DoSetBlending() + */ + virtual void DoSetBlending( Context& context, BufferIndex bufferIndex ); + protected: // TextureObserver implementation /** @@ -214,10 +237,13 @@ private: Vector2 mGeometrySize; ResourceId mTextureId; + BlendingOptions mBlendingOptions; + // flags MeshType mMeshType : 3; // 4 values fits in 3 bits just fine bool mIsMeshGenerated : 1; bool mBorderInPixels : 1; + bool mUseBlend : 1; ///< True if blending should be enabled, 1 bit is enough bool mUsePixelArea : 1; }; diff --git a/dali/internal/render/renderers/scene-graph-renderer.cpp b/dali/internal/render/renderers/scene-graph-renderer.cpp index e612695..3a77482 100644 --- a/dali/internal/render/renderers/scene-graph-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-renderer.cpp @@ -123,21 +123,6 @@ void Renderer::SetShader( Shader* shader ) mShader = shader; } -void Renderer::SetUseBlend( bool useBlend ) -{ - mUseBlend = useBlend; -} - -void Renderer::SetBlendingOptions( unsigned int options ) -{ - mBlendingOptions.SetBitmask( options ); -} - -void Renderer::SetBlendColor( const Vector4& color ) -{ - mBlendingOptions.SetBlendColor( color ); -} - void Renderer::SetCullFace( CullFaceMode mode ) { DALI_ASSERT_DEBUG(mode >= CullNone && mode <= CullFrontAndBack); @@ -253,42 +238,12 @@ void Renderer::DoSetCullFaceMode(Context& context, BufferIndex bufferIndex ) context.CullFace( mCullFaceMode ); } -// can be overridden by deriving class -void Renderer::DoSetBlending(Context& context, BufferIndex bufferIndex ) -{ - // Enables/disables blending mode. - context.SetBlend( mUseBlend ); - - // Set the blend color - const Vector4* const customColor = mBlendingOptions.GetBlendColor(); - if( customColor ) - { - context.SetCustomBlendColor( *customColor ); - } - 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() ); - -} - Renderer::Renderer( NodeDataProvider& dataprovider ) : mDataProvider( dataprovider ), mContextDELETEME(NULL), mTextureCacheDELETEME( NULL ), mShader( NULL ), mSamplerBitfield( ImageSampler::PackBitfield( FilterMode::DEFAULT, FilterMode::DEFAULT ) ), - mUseBlend( false ), mCullFaceMode( CullNone ) { } diff --git a/dali/internal/render/renderers/scene-graph-renderer.h b/dali/internal/render/renderers/scene-graph-renderer.h index c5ebb7c..01bf071 100644 --- a/dali/internal/render/renderers/scene-graph-renderer.h +++ b/dali/internal/render/renderers/scene-graph-renderer.h @@ -73,24 +73,6 @@ public: void SetShader( Shader* shader ); /** - * Set whether the ImageRenderer should use blending - * @param[in] useBlend True if blending should be used. - */ - void SetUseBlend( bool useBlend ); - - /** - * Set the blending options. - * @param[in] options A bitmask of blending options. - */ - void SetBlendingOptions( unsigned int options ); - - /** - * Set the blend color. - * @param[in] color The new blend-color. - */ - void SetBlendColor( const Vector4& color ); - - /** * Set the face-culling mode. * @param[in] mode The face-culling mode. */ @@ -176,7 +158,7 @@ private: * Called from Render prior to DoRender(). Default method to set blending options * @todo MESH_REWORK Remove after merge */ - virtual void DoSetBlending( Context& context, BufferIndex bufferIndex ); + virtual void DoSetBlending( Context& context, BufferIndex bufferIndex ) = 0; /** * Called from Render; implemented in derived classes. @@ -198,10 +180,8 @@ protected: Shader* mShader; unsigned int mSamplerBitfield; ///< Sampler options used for texture filtering - bool mUseBlend:1; ///< True if blending should be enabled, 1 bit is enough private: - BlendingOptions mBlendingOptions; CullFaceMode mCullFaceMode:3; ///< cullface enum, 3 bits is enough }; diff --git a/dali/internal/update/manager/prepare-render-algorithms.cpp b/dali/internal/update/manager/prepare-render-algorithms.cpp index 51e1699..ea09f44 100644 --- a/dali/internal/update/manager/prepare-render-algorithms.cpp +++ b/dali/internal/update/manager/prepare-render-algorithms.cpp @@ -64,7 +64,7 @@ void PrepareRenderables( BufferIndex updateBufferIndex, RenderableAttachmentCont for ( RenderableAttachmentIter iter = renderableList.begin(); iter != endIter; ++iter ) { RenderableAttachment& renderable = **iter; - renderable.PrepareRender( updateBufferIndex ); + renderable.DoPrepareRender( updateBufferIndex ); } } diff --git a/dali/internal/update/node-attachments/scene-graph-image-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-image-attachment.cpp index 59cb27d..be17b89 100644 --- a/dali/internal/update/node-attachments/scene-graph-image-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-image-attachment.cpp @@ -65,7 +65,8 @@ ImageAttachment::ImageAttachment( unsigned int textureId ) mIsPixelAreaSet( false ), mPreviousRefreshHints( 0 ), mStyle( Dali::ImageActor::STYLE_QUAD ), - mCullFaceMode( CullNone ) + mCullFaceMode( CullNone ), + mUseBlend( false ) { } @@ -209,25 +210,25 @@ void ImageAttachment::SetBorder( BufferIndex updateBufferIndex, const Vector4& b void ImageAttachment::SetBlendingOptions( BufferIndex updateBufferIndex, unsigned int options ) { // Blending options are forwarded to renderer in render-thread - typedef MessageValue1< Renderer, unsigned int > DerivedType; + typedef MessageValue1< ImageRenderer, unsigned int > DerivedType; // Reserve some memory inside the render queue unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &GetRenderer(), &Renderer::SetBlendingOptions, options ); + new (slot) DerivedType( mImageRenderer, &ImageRenderer::SetBlendingOptions, options ); } void ImageAttachment::SetBlendColor( BufferIndex updateBufferIndex, const Vector4& color ) { // Blend color is forwarded to renderer in render-thread - typedef MessageValue1< Renderer, Vector4 > DerivedType; + typedef MessageValue1< ImageRenderer, Vector4 > DerivedType; // Reserve some memory inside the render queue unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &GetRenderer(), &Renderer::SetBlendColor, color ); + new (slot) DerivedType( mImageRenderer, &ImageRenderer::SetBlendColor, color ); } void ImageAttachment::SetCullFace( BufferIndex updateBufferIndex, CullFaceMode mode ) @@ -428,6 +429,22 @@ void ImageAttachment::DoPrepareRender( BufferIndex updateBufferIndex ) mRefreshMeshData = false; } + + bool blend = !IsFullyOpaque( updateBufferIndex ); + + if ( mUseBlend != blend ) + { + mUseBlend = blend; + + // Enable/disable blending in the next render + typedef MessageValue1< ImageRenderer, bool > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( mImageRenderer, &ImageRenderer::SetUseBlend, blend ); + } } void RenderableAttachment::SetBlendingMode( BlendingMode::Type mode ) diff --git a/dali/internal/update/node-attachments/scene-graph-image-attachment.h b/dali/internal/update/node-attachments/scene-graph-image-attachment.h index 1523d10..ae2e6c3 100644 --- a/dali/internal/update/node-attachments/scene-graph-image-attachment.h +++ b/dali/internal/update/node-attachments/scene-graph-image-attachment.h @@ -253,6 +253,7 @@ private: // Data int mPreviousRefreshHints : 4; ///< The shader geometry hints, when the vertex buffer was last refreshed, 4 bits is enough as there's 4 flags Style mStyle : 2; ///< rendering style, 2 bits is enough as only 2 values in the enum CullFaceMode mCullFaceMode : 3; ///< Cullface mode, 3 bits is enough for 4 values + bool mUseBlend : 1; ///< True if the attachment & renderer should be considered opaque for sorting and blending. BitmapMetadata mBitmapMetadata;///< The bitmap metadata Vector2 mGeometrySize; ///< The size of the currently used geometry diff --git a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp index a27e960..b4a30ea 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.cpp @@ -48,7 +48,6 @@ RenderableAttachment::RenderableAttachment( bool usesGeometryScaling ) mBlendingMode( Dali::ImageActor::DEFAULT_BLENDING_MODE ), mUsesGeometryScaling( usesGeometryScaling ), mScaleForSizeDirty( true ), - mUseBlend( false ), mHasSizeAndColorFlag( false ), mResourcesReady( false ), mFinishedResourceAcquisition( false ), @@ -211,30 +210,6 @@ void RenderableAttachment::GetReadyAndComplete(bool& ready, bool& complete) cons } } -void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex ) -{ - // call the derived class first as it might change its state regarding blending - DoPrepareRender( updateBufferIndex ); - - // @todo MESH_REWORK Remove remainder of method after removing ImageAttachment - - bool blend = !IsFullyOpaque( updateBufferIndex ); - - if ( mUseBlend != blend ) - { - mUseBlend = blend; - - // Enable/disable blending in the next render - typedef MessageValue1< Renderer, bool > DerivedType; - - // Reserve some memory inside the render queue - unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) ); - - // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &GetRenderer(), &Renderer::SetUseBlend, blend ); - } -} - RenderableAttachment* RenderableAttachment::GetRenderable() { return this; diff --git a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h index 0f01208..d4ba11c 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h +++ b/dali/internal/update/node-attachments/scene-graph-renderable-attachment.h @@ -176,13 +176,6 @@ public: // For use during in the update algorithm only */ void GetReadyAndComplete(bool& ready, bool& complete) const; - /** - * Prepare the object for rendering. - * This is called by the UpdateManager when an object is due to be rendered in the current frame. - * @param[in] updateBufferIndex The current update buffer index. - */ - void PrepareRender( BufferIndex updateBufferIndex ); - public: // API for derived classes /** @@ -212,7 +205,9 @@ public: // API for derived classes virtual bool DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager ) = 0; /** - * @copydoc RenderableAttachment::PrepareRender() + * Prepare the object for rendering. + * This is called by the UpdateManager when an object is due to be rendered in the current frame. + * @param[in] updateBufferIndex The current update buffer index. */ virtual void DoPrepareRender( BufferIndex updateBufferIndex ) = 0; @@ -283,7 +278,6 @@ protected: bool mUsesGeometryScaling:1; ///< True if the derived renderer uses scaling. bool mScaleForSizeDirty:1; ///< True if mScaleForSize has changed in the current frame. - bool mUseBlend:1; ///< True if the attachment & renderer should be considered opaque for sorting and blending. bool mHasSizeAndColorFlag:1; ///< Set during the update algorithm to tell whether this renderer can potentially be seen bool mResourcesReady:1; ///< Set during the Update algorithm; true if the attachment has resources ready for the current frame. bool mFinishedResourceAcquisition:1; ///< Set during DoPrepareResources; true if ready & all resource acquisition has finished (successfully or otherwise) diff --git a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp index eac06ef..8bb714e 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp +++ b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.cpp @@ -70,6 +70,7 @@ RendererAttachment::RendererAttachment() mRegenerateUniformMap(REGENERATE_UNIFORM_MAP), mResendDataProviders(false), mResendGeometry(false), + mUseBlend( false ), mDepthIndex(0) { mUniformMapChanged[0]=false; @@ -384,6 +385,13 @@ void RendererAttachment::DoPrepareRender( BufferIndex updateBufferIndex ) mRegenerateUniformMap--; } + bool blend = !IsFullyOpaque( updateBufferIndex ); + if( mUseBlend != blend ) + { + mUseBlend = blend; + mResendDataProviders = true; + } + if( mResendDataProviders ) { RenderDataProvider* dataProvider = NewRenderDataProvider(); @@ -494,6 +502,7 @@ RenderDataProvider* RendererAttachment::NewRenderDataProvider() dataProvider->mMaterialDataProvider = mMaterial; dataProvider->mUniformMapDataProvider = this; dataProvider->mShader = mMaterial->GetShader(); + dataProvider->mUseBlend = mUseBlend; Vector& samplers = mMaterial->GetSamplers(); dataProvider->mSamplers.Reserve( samplers.Count() ); diff --git a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h index b7c4e7a..3fd48dd 100644 --- a/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h +++ b/dali/internal/update/node-attachments/scene-graph-renderer-attachment.h @@ -234,7 +234,7 @@ private: bool mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame bool mResendDataProviders : 1; ///< True if the data providers should be resent to the renderer bool mResendGeometry : 1; ///< True if geometry should be resent to the renderer - + bool mUseBlend : 1; ///< True if the attachment & renderer should be considered opaque for sorting and blending. public: // Properties int mDepthIndex; ///< Used only in PrepareRenderInstructions -- 2.7.4