From: Kimmo Hoikka Date: Tue, 6 May 2014 12:50:23 +0000 (+0100) Subject: ContextObserver removal, part II: Its gone X-Git-Tag: dali-2014-wk20-release~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=90f7f2773c33b4bf221f28ca0dbbfc134b12198d;p=platform%2Fcore%2Fuifw%2Fdali-core.git ContextObserver removal, part II: Its gone [Issue#] N/A [Problem] memory consumption [Cause] observer pattern causes classes to be virtual unnecessarily [Solution] remove observer pattern Change-Id: Id0223b54cf989caf12a55ccadcaf9f48dff9a5b9 Signed-off-by: Ferran Sole --- diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index 443894200..1fedc18e8 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -211,7 +211,7 @@ void Core::ContextCreated() void Core::ContextToBeDestroyed() { - mRenderManager->ContextToBeDestroyed(); + mRenderManager->ContextDestroyed(); } void Core::SurfaceResized(unsigned int width, unsigned int height) diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 23ee5b40a..092df858e 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -95,10 +95,10 @@ struct RenderManager::Impl dynamicsDebugRenderer( NULL ), frameCount( 0 ), renderBufferIndex( SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX ), - mDefaultSurfaceRect(), - mRendererContainer(), - mMaterials(), - mRenderersAdded( false ) + defaultSurfaceRect(), + rendererContainer(), + materials(), + renderersAdded( false ) { } @@ -134,9 +134,7 @@ struct RenderManager::Impl } // the order is important for destruction, - // programs, textures and gpubuffers are context observers so delete context last - // programs are owned by context at the moment. renderers have to be deleted - // first as they observe texture cache and own the gpubuffers + // programs are owned by context at the moment. Context context; ///< holds the GL state RenderQueue renderQueue; ///< A message queue for receiving messages from the update-thread. TextureCache textureCache; ///< Cache for all GL textures @@ -157,12 +155,12 @@ struct RenderManager::Impl unsigned int frameCount; ///< The current frame count BufferIndex renderBufferIndex; ///< The index of the buffer to read from; this is opposite of the "update" buffer - Rect mDefaultSurfaceRect; ///< Rectangle for the default surface we are rendering to + Rect defaultSurfaceRect; ///< Rectangle for the default surface we are rendering to - RendererOwnerContainer mRendererContainer; ///< List of owned renderers - RenderMaterialContainer mMaterials; ///< List of owned render materials + RendererOwnerContainer rendererContainer; ///< List of owned renderers + RenderMaterialContainer materials; ///< List of owned render materials - bool mRenderersAdded; + bool renderersAdded; RenderTrackerContainer mRenderTrackers; ///< List of render trackers }; @@ -201,14 +199,27 @@ Context& RenderManager::GetContext() void RenderManager::ContextCreated() { - // TODO inform renderers etc directly rather than through context observer mImpl->context.GlContextCreated(); + + // renderers, textures and gpu buffers cannot reinitialize themselves + // so they rely on someone reloading the data for them } -void RenderManager::ContextToBeDestroyed() +void RenderManager::ContextDestroyed() { - // TODO inform renderers etc directly rather than through context observer - mImpl->context.GlContextToBeDestroyed(); + mImpl->context.GlContextDestroyed(); + + // inform texture cache + mImpl->textureCache.GlContextDestroyed(); + + // inform renderers + RendererOwnerContainer::Iterator end = mImpl->rendererContainer.End(); + RendererOwnerContainer::Iterator iter = mImpl->rendererContainer.Begin(); + for( ; iter != end; ++iter ) + { + GlResourceOwner* renderer = *iter; + renderer->GlContextDestroyed(); + } } void RenderManager::DispatchPostProcessRequest(ResourcePostProcessRequest& request) @@ -242,7 +253,7 @@ void RenderManager::InitializeDynamicsDebugRenderer(DynamicsDebugRenderer* debug void RenderManager::SetDefaultSurfaceRect(const Rect& rect) { - mImpl->mDefaultSurfaceRect = rect; + mImpl->defaultSurfaceRect = rect; } void RenderManager::AddRenderer( Renderer* renderer ) @@ -250,11 +261,11 @@ void RenderManager::AddRenderer( Renderer* renderer ) // Initialize the renderer as we are now in render thread renderer->Initialize( mImpl->context, mImpl->textureCache ); - mImpl->mRendererContainer.PushBack( renderer ); + mImpl->rendererContainer.PushBack( renderer ); - if( !mImpl->mRenderersAdded ) + if( !mImpl->renderersAdded ) { - mImpl->mRenderersAdded = true; + mImpl->renderersAdded = true; } } @@ -262,7 +273,7 @@ void RenderManager::RemoveRenderer( Renderer* renderer ) { DALI_ASSERT_DEBUG( NULL != renderer ); - RendererOwnerContainer& renderers = mImpl->mRendererContainer; + RendererOwnerContainer& renderers = mImpl->rendererContainer; // Find the renderer for ( RendererOwnerIter iter = renderers.Begin(); iter != renderers.End(); ++iter ) @@ -279,7 +290,7 @@ void RenderManager::AddRenderMaterial( RenderMaterial* renderMaterial ) { DALI_ASSERT_DEBUG( NULL != renderMaterial ); - mImpl->mMaterials.PushBack( renderMaterial ); + mImpl->materials.PushBack( renderMaterial ); renderMaterial->Initialize( mImpl->textureCache ); } @@ -287,7 +298,7 @@ void RenderManager::RemoveRenderMaterial( RenderMaterial* renderMaterial ) { DALI_ASSERT_DEBUG( NULL != renderMaterial ); - RenderMaterialContainer& materials = mImpl->mMaterials; + RenderMaterialContainer& materials = mImpl->materials; // Find the render material and destroy it for ( RenderMaterialIter iter = materials.Begin(); iter != materials.End(); ++iter ) @@ -316,6 +327,9 @@ bool RenderManager::Render( Integration::RenderStatus& status ) { DALI_PRINT_RENDER_START( mImpl->renderBufferIndex ); + // Core::Render documents that GL context must be current before calling Render + DALI_ASSERT_DEBUG( mImpl->context.IsGlContextCreated() ); + status.SetHasRendered( false ); // Increment the frame count at the beginning of each frame @@ -329,15 +343,15 @@ bool RenderManager::Render( Integration::RenderStatus& status ) mImpl->renderQueue.ProcessMessages( mImpl->renderBufferIndex ); //No need to make any gl calls if we don't have any renderers to render during startup. - if(mImpl->mRenderersAdded) + if(mImpl->renderersAdded) { // switch rendering to adaptor provided (default) buffer mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, 0 ); - mImpl->context.Viewport( mImpl->mDefaultSurfaceRect.x, - mImpl->mDefaultSurfaceRect.y, - mImpl->mDefaultSurfaceRect.width, - mImpl->mDefaultSurfaceRect.height ); + mImpl->context.Viewport( mImpl->defaultSurfaceRect.x, + mImpl->defaultSurfaceRect.y, + mImpl->defaultSurfaceRect.width, + mImpl->defaultSurfaceRect.height ); mImpl->context.ClearColor( mImpl->backgroundColor.r, mImpl->backgroundColor.g, @@ -452,12 +466,12 @@ void RenderManager::DoRender( RenderInstruction& instruction, float elapsedTime if ( instruction.mIsViewportSet ) { // For glViewport the lower-left corner is (0,0) - const int y = ( mImpl->mDefaultSurfaceRect.height - instruction.mViewport.height ) - instruction.mViewport.y; + const int y = ( mImpl->defaultSurfaceRect.height - instruction.mViewport.height ) - instruction.mViewport.y; viewportRect.Set( instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height ); } else { - viewportRect = mImpl->mDefaultSurfaceRect; + viewportRect = mImpl->defaultSurfaceRect; } } diff --git a/dali/internal/render/common/render-manager.h b/dali/internal/render/common/render-manager.h index 6d080a52d..33dc702ca 100644 --- a/dali/internal/render/common/render-manager.h +++ b/dali/internal/render/common/render-manager.h @@ -99,7 +99,7 @@ public: /** * @copydoc Dali::Integration::Core::ContextToBeDestroyed() */ - void ContextToBeDestroyed(); + void ContextDestroyed(); /** * Dispatch requests onto the postProcessResourcesQueue diff --git a/dali/internal/render/gl-resources/context-observer.h b/dali/internal/render/gl-resources/context-observer.h deleted file mode 100644 index 35ae0dc17..000000000 --- a/dali/internal/render/gl-resources/context-observer.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef __DALI_INTERNAL_CONTEXT_OBSERVER_H__ -#define __DALI_INTERNAL_CONTEXT_OBSERVER_H__ - -// -// Copyright (c) 2014 Samsung Electronics Co., Ltd. -// -// Licensed under the Flora License, Version 1.0 (the License); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://floralicense.org/license/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an AS IS BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace Dali -{ - -namespace Internal -{ - -/** - * Context observers are notified when the OpenGL context is created or destroyed. - */ -class ContextObserver -{ -public: - - /** - * Called when the OpenGL context has been created. - */ - virtual void GlContextCreated() = 0; - - /** - * Called when the OpenGL context is about to be destroyed. - * The observer should free any GL resources held. - */ - virtual void GlContextToBeDestroyed() = 0; -}; - -} // namespace Internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_CONTEXT_OBSERVER_H__ diff --git a/dali/internal/render/gl-resources/context.cpp b/dali/internal/render/gl-resources/context.cpp index 1ba145306..9dd2f68fc 100644 --- a/dali/internal/render/gl-resources/context.cpp +++ b/dali/internal/render/gl-resources/context.cpp @@ -23,7 +23,6 @@ // INTERNAL INCLUDES #include -#include #include #include #include @@ -114,8 +113,6 @@ Context::~Context() // release the cached programs std::for_each(mProgramCache.begin(), mProgramCache.end(), deletePrograms); mProgramCache.clear(); - - DALI_ASSERT_DEBUG(mObservers.empty()); } void Context::GlContextCreated() @@ -127,13 +124,6 @@ void Context::GlContextCreated() // Set the initial GL state, and check it. ResetGlState(); - const std::set::iterator end = mObservers.end(); - for ( std::set::iterator it = mObservers.begin(); - it != end; ++it ) - { - (*it)->GlContextCreated(); - } - const ProgramContainer::iterator endp = mProgramCache.end(); for ( ProgramContainer::iterator itp = mProgramCache.begin(); itp != endp; ++itp ) { @@ -141,17 +131,8 @@ void Context::GlContextCreated() } } -void Context::GlContextToBeDestroyed() +void Context::GlContextDestroyed() { - DALI_ASSERT_DEBUG(mGlContextCreated); - - const std::set::iterator end = mObservers.end(); - for ( std::set::iterator it = mObservers.begin(); - it != end; ++it ) - { - (*it)->GlContextToBeDestroyed(); - } - const ProgramContainer::iterator endp = mProgramCache.end(); for ( ProgramContainer::iterator itp = mProgramCache.begin(); itp != endp; ++itp ) { @@ -161,16 +142,6 @@ void Context::GlContextToBeDestroyed() mGlContextCreated = false; } -void Context::AddObserver(ContextObserver& observer) -{ - mObservers.insert(&observer); -} - -void Context::RemoveObserver(ContextObserver& observer) -{ - mObservers.erase(&observer); -} - const char* Context::ErrorToString( GLenum errorCode ) { for( unsigned int i = 0; i < sizeof(errors) / sizeof(errors[0]); ++i) diff --git a/dali/internal/render/gl-resources/context.h b/dali/internal/render/gl-resources/context.h index 2517b0cbe..a737f347a 100644 --- a/dali/internal/render/gl-resources/context.h +++ b/dali/internal/render/gl-resources/context.h @@ -19,7 +19,6 @@ // INTERNAL INCLUDES #include -#include #include #include #include @@ -35,7 +34,6 @@ namespace Dali namespace Internal { -class ContextObserver; class Program; // to be able to cache programs // wrap gl calls with CHECK_GL eg "CHECK_GL( *this, glBindTexture(textureId) );" @@ -53,7 +51,6 @@ class Program; // to be able to cache programs /** * Context records the current GL state, and provides access to the OpenGL ES 2.0 API. - * Observers will be notified when the GL context is created/destroyed. * Context avoids duplicate GL calls, if the same setting etc. is requested repeatedly. */ class Context @@ -82,15 +79,13 @@ public: /** * Called when the GL context has been created. - * @post Context observers will be notified. */ void GlContextCreated(); /** * Called when the GL context is about to be destroyed. - * @post Context observers will be notified, and should free any GL resources held. */ - void GlContextToBeDestroyed(); + void GlContextDestroyed(); /** * Query whether the OpenGL context has been created. @@ -98,20 +93,6 @@ public: */ bool IsGlContextCreated() { return mGlContextCreated; } - /** - * Adds an observer to the Context object. - * The observer is responsible for calling RemoveObserver() before destruction. - * @param[in] observer The observer to add. - */ - void AddObserver(ContextObserver& observer); - - /** - * Removes an observer from the Context object. - * The observer must call this method before it is destroyed. - * @param[in] observer The observer to remove. - */ - void RemoveObserver(ContextObserver& observer); - /** * @return the GLAbstraction */ @@ -602,9 +583,13 @@ public: */ void DeleteBuffers(GLsizei n, const GLuint* buffers) { - LOG_GL("DeleteBuffers %d %p\n", n, buffers); - CHECK_GL( *this, mGlAbstraction.DeleteBuffers(n, buffers) ); - + // TODO: this is to prevent mesh destructor from doing GL calls when DALi core is being deleted + // can be taken out once render manages either knows about meshes or gpubuffers and can tell them directly that context is lost + if( this->IsGlContextCreated() ) + { + LOG_GL("DeleteBuffers %d %p\n", n, buffers); + CHECK_GL( *this, mGlAbstraction.DeleteBuffers(n, buffers) ); + } // reset the cached buffer id's // fixes problem where some drivers will a generate a buffer with the // same id, as the last deleted buffer id. @@ -1771,8 +1756,6 @@ private: // Data bool mVertexAttributeCachedState[ MAX_ATTRIBUTE_CACHE_SIZE ]; ///< Value cache for Enable Vertex Attribute bool mVertexAttributeCurrentState[ MAX_ATTRIBUTE_CACHE_SIZE ]; ///< Current state on the driver for Enable Vertex Attribute - std::set mObservers; - Program* mCurrentProgram; typedef std::map< std::size_t, Program* > ProgramContainer; ProgramContainer mProgramCache; /// program cache diff --git a/dali/internal/render/gl-resources/gl-resource-owner.h b/dali/internal/render/gl-resources/gl-resource-owner.h index fdf9e089c..5600a661c 100644 --- a/dali/internal/render/gl-resources/gl-resource-owner.h +++ b/dali/internal/render/gl-resources/gl-resource-owner.h @@ -35,14 +35,24 @@ public: * Virtual destructor. */ virtual ~GlResourceOwner() - { - } + { } + + /** + * Reset all GL resources. + * This method is called when context is or has been deleted. + * Context cannot be called from this method. + * @pre This method can only be called from the render-thread. + */ + virtual void GlContextDestroyed() = 0; /** * Release all GL resources. - * @pre This method is should only be called from the render-thread. + * This means releasing buffer objects, textures. etc + * Context can be used, unless GlContextDestroyed has been called + * @pre This method can only be called from the render-thread. */ virtual void GlCleanup() = 0; + }; } // namespace Internal diff --git a/dali/internal/render/gl-resources/gpu-buffer.cpp b/dali/internal/render/gl-resources/gpu-buffer.cpp index bdbc2f956..40564e288 100644 --- a/dali/internal/render/gl-resources/gpu-buffer.cpp +++ b/dali/internal/render/gl-resources/gpu-buffer.cpp @@ -97,16 +97,17 @@ GpuBuffer::GpuBuffer( Context& context, Target target, Usage usage ) mUsage( usage ), mBufferCreated( false ) { - // the buffer is owned by the GPU so if we lose context, we lose the buffer - // so we need to know when we lose context - mContext.AddObserver(*this); } GpuBuffer::~GpuBuffer() { - mContext.RemoveObserver(*this); - - GlContextToBeDestroyed(); + // If we have a buffer then delete it. + if (mBufferId) + { + // If a buffer object that is currently bound is deleted, the binding reverts to 0 + // (the absence of any buffer object, which reverts to client memory usage) + mContext.DeleteBuffers(1,&mBufferId); + } } /* @@ -183,33 +184,9 @@ bool GpuBuffer::BufferIsValid() const return mBufferCreated && (0 != mCapacity ); } -/* - * If the context is about to go, and we have a buffer then delete it. - */ -void GpuBuffer::GlContextToBeDestroyed() -{ - if (mBufferId) - { - // If the buffer is currently bound, then unbind it by setting the - // currently bound buffer to zero. - if (mContext.GetCurrentBoundArrayBuffer( TypeAsGlEnum( mTarget ) ) == mBufferId) - { - BindNoChecks(0); - } - - mCapacity = 0; - mSize = 0; - mContext.DeleteBuffers(1,&mBufferId); - mBufferId = 0; - mBufferCreated = false; - } -} - -void GpuBuffer::GlContextCreated() +void GpuBuffer::GlContextDestroyed() { - // set some default values, just incase we don't get a - // GlContextToBeDestroyed when the context is lost and then - // is recreated (should never happen). + // If the context is destroyed, GL would have released the buffer. mCapacity = 0; mSize = 0; mBufferId = 0; diff --git a/dali/internal/render/gl-resources/gpu-buffer.h b/dali/internal/render/gl-resources/gpu-buffer.h index ea37380c5..baf3c059f 100644 --- a/dali/internal/render/gl-resources/gpu-buffer.h +++ b/dali/internal/render/gl-resources/gpu-buffer.h @@ -19,7 +19,6 @@ // INTERNAL INCLUDES #include -#include namespace Dali { @@ -36,9 +35,8 @@ namespace Internal * The buffer allows data to be stored in high-performance * graphics memory on the server side and * promotes efficient data transfer. - * */ -class GpuBuffer : public ContextObserver +class GpuBuffer { public: @@ -57,8 +55,8 @@ public: */ enum Usage { - STREAM_DRAW, ///< GL_STREAM_DRAW - STATIC_DRAW, ///< GL_STATIC_DRAW + STREAM_DRAW, ///< GL_STREAM_DRAW + STATIC_DRAW, ///< GL_STATIC_DRAW DYNAMIC_DRAW, ///< GL_DYNAMIC_DRAW }; @@ -73,9 +71,9 @@ public: GpuBuffer( Context& context, Target target, Usage usage ); /** - * Destructor + * Destructor, non virtual as no virtual methods or inheritance */ - virtual ~GpuBuffer(); + ~GpuBuffer(); /** * @@ -105,17 +103,10 @@ public: return mSize; } -private: // From Context::Observer - - /** - * @copydoc ContextObserver::GlContextToBeDestroyed - */ - virtual void GlContextToBeDestroyed(); - /** - * @copydoc ContextObserver::GlContextCreated + * Needs to be called when GL context is destroyed */ - virtual void GlContextCreated(); + void GlContextDestroyed(); private: diff --git a/dali/internal/render/gl-resources/texture-cache.cpp b/dali/internal/render/gl-resources/texture-cache.cpp index b2726c164..c06fc0ab2 100644 --- a/dali/internal/render/gl-resources/texture-cache.cpp +++ b/dali/internal/render/gl-resources/texture-cache.cpp @@ -354,6 +354,16 @@ void TextureCache::RemoveObserver( ResourceId id, TextureObserver* observer ) } } +void TextureCache::GlContextDestroyed() +{ + TextureIter end = mTextures.end(); + TextureIter iter = mTextures.begin(); + for( ; iter != end; ++iter ) + { + (*iter->second).GlContextDestroyed(); // map holds intrusive pointers + } +} + /******************************************************************************** ********************** Implements TextureCacheDispatcher ********************* ********************************************************************************/ diff --git a/dali/internal/render/gl-resources/texture-cache.h b/dali/internal/render/gl-resources/texture-cache.h index 686fcfbf5..ab132d704 100644 --- a/dali/internal/render/gl-resources/texture-cache.h +++ b/dali/internal/render/gl-resources/texture-cache.h @@ -208,6 +208,12 @@ public: */ void RemoveObserver( ResourceId id, TextureObserver* observer ); + /** + * Reset all textures. + * This method is called when context is or has been deleted. + */ + void GlContextDestroyed(); + protected: // Implements TextureCacheDispatcher /** diff --git a/dali/internal/render/gl-resources/texture.cpp b/dali/internal/render/gl-resources/texture.cpp index aac69f481..f5b3933b7 100644 --- a/dali/internal/render/gl-resources/texture.cpp +++ b/dali/internal/render/gl-resources/texture.cpp @@ -52,12 +52,10 @@ Texture::Texture(Context& context, mPixelFormat(pixelFormat), mDiscarded(false) { - mContext.AddObserver(*this); } Texture::~Texture() { - mContext.RemoveObserver(*this); // GlCleanup() should already have been called by TextureCache ensuring the resource is destroyed // on the render thread. (And avoiding a potentially problematic virtual call in the destructor) } @@ -103,9 +101,15 @@ bool Texture::Bind(GLenum target, GLenum textureunit ) return created; } +void Texture::GlContextDestroyed() +{ + // texture is gone + mId = 0; +} + void Texture::GlCleanup() { - // otherwise, delete the gl texture + // delete the gl texture if (mId != 0) { mContext.DeleteTextures(1,&mId); @@ -155,24 +159,6 @@ Pixel::Format Texture::GetPixelFormat() const return mPixelFormat; } -/* - * When an OpenGL context is created and made active we don't - * do anything, because we use lazy binding. - * This means when a texture is required that's when it's loaded - * into OpenGL. - */ -void Texture::GlContextCreated() -{ -} - -/* - * From Context::Observer, called just before the OpenGL context is destroyed. - */ -void Texture::GlContextToBeDestroyed() -{ - GlCleanup(); -} - void Texture::GetTextureCoordinates(UvRect& uv, const PixelArea* pixelArea) { if( pixelArea == NULL ) diff --git a/dali/internal/render/gl-resources/texture.h b/dali/internal/render/gl-resources/texture.h index 4d6ae1e28..f22e382b8 100644 --- a/dali/internal/render/gl-resources/texture.h +++ b/dali/internal/render/gl-resources/texture.h @@ -20,7 +20,6 @@ // INTERNAL INCLUDES #include #include -#include #include #include #include @@ -45,7 +44,6 @@ struct Vertex2D; * Texture class. */ class Texture: public RefObject, - public ContextObserver, public GlResourceOwner { public: @@ -170,18 +168,6 @@ public: */ void GetTextureCoordinates(UvRect& uv, const PixelArea* pixelArea = NULL); -public: // From Context::Observer - - /** - * From Context::Observer, called when the OpenGL context is active. - */ - virtual void GlContextCreated(); - - /** - * From Context::Observer, called just before the OpenGL context is destroyed. - */ - virtual void GlContextToBeDestroyed(); - protected: /** @@ -216,6 +202,7 @@ protected: * @return true on success */ virtual bool CreateGlTexture() = 0; + public: /** * Destructor. @@ -226,8 +213,12 @@ public: public: // From GlResourceOwner /** - * Delete the GL texture. - * @pre This method is should only be called from the render-thread. + * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed() + */ + virtual void GlContextDestroyed(); + + /** + * @copydoc Dali::Internal::GlResourceOwner::GlCleanup() */ virtual void GlCleanup(); diff --git a/dali/internal/render/renderers/scene-graph-image-renderer.cpp b/dali/internal/render/renderers/scene-graph-image-renderer.cpp index fd1009094..44699c82a 100644 --- a/dali/internal/render/renderers/scene-graph-image-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-image-renderer.cpp @@ -165,17 +165,24 @@ void ImageRenderer::TextureDiscarded( ResourceId textureId ) mTexture = NULL; } -void ImageRenderer::GlCleanup() +void ImageRenderer::GlContextDestroyed() { - if (mVertexBuffer) + if( mVertexBuffer ) { - mVertexBuffer.Reset(); + mVertexBuffer->GlContextDestroyed(); } - - if (mIndexBuffer) + if( mIndexBuffer ) { - mIndexBuffer.Reset(); + mIndexBuffer->GlContextDestroyed(); } + // force recreation of the geometry in next render + mIsMeshGenerated = false; +} + +void ImageRenderer::GlCleanup() +{ + mVertexBuffer.Reset(); + mIndexBuffer.Reset(); } bool ImageRenderer::RequiresDepthTest() const diff --git a/dali/internal/render/renderers/scene-graph-image-renderer.h b/dali/internal/render/renderers/scene-graph-image-renderer.h index 2eb6f542c..c08fb1aa8 100644 --- a/dali/internal/render/renderers/scene-graph-image-renderer.h +++ b/dali/internal/render/renderers/scene-graph-image-renderer.h @@ -92,6 +92,11 @@ public: */ void CalculateMeshData( MeshType type, const Vector2& targetSize, bool usePixelArea ); + /** + * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed() + */ + virtual void GlContextDestroyed(); + /** * @copydoc Dali::Internal::GlResourceOwner::GlCleanup() */ diff --git a/dali/internal/render/renderers/scene-graph-mesh-renderer.cpp b/dali/internal/render/renderers/scene-graph-mesh-renderer.cpp index e5c40fc4e..bbed49c56 100644 --- a/dali/internal/render/renderers/scene-graph-mesh-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-mesh-renderer.cpp @@ -80,6 +80,22 @@ MeshRenderer::~MeshRenderer() { } +void MeshRenderer::GlContextDestroyed() +{ + MeshInfo& meshInfo0 = mMeshInfo[ 0 ]; + Mesh* mesh = meshInfo0.mesh; + if( mesh ) + { + mesh->GlContextDestroyed(); + } + MeshInfo& meshInfo1 = mMeshInfo[ 1 ]; + mesh = meshInfo1.mesh; + if( mesh ) + { + mesh->GlContextDestroyed(); + } +} + void MeshRenderer::GlCleanup() { // MeshRenderer does not own any GL resources diff --git a/dali/internal/render/renderers/scene-graph-mesh-renderer.h b/dali/internal/render/renderers/scene-graph-mesh-renderer.h index 0a59f7b7a..dc91a63f0 100644 --- a/dali/internal/render/renderers/scene-graph-mesh-renderer.h +++ b/dali/internal/render/renderers/scene-graph-mesh-renderer.h @@ -99,6 +99,11 @@ public: private: + /** + * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed() + */ + virtual void GlContextDestroyed(); + /** * @copydoc Dali::Internal::GlResourceOwner::GlCleanup() */ diff --git a/dali/internal/render/renderers/scene-graph-text-renderer.cpp b/dali/internal/render/renderers/scene-graph-text-renderer.cpp index 38a5396e6..18cc3da70 100644 --- a/dali/internal/render/renderers/scene-graph-text-renderer.cpp +++ b/dali/internal/render/renderers/scene-graph-text-renderer.cpp @@ -254,11 +254,23 @@ void TextRenderer::SetDropShadow( const bool enable, const Vector4& color, const mTextParameters->SetShadow( enable, color, offset, size ); } -void TextRenderer::SetSmoothEdge( const float params ) +void TextRenderer::SetSmoothEdge( float params ) { mSmoothing = params; } +void TextRenderer::GlContextDestroyed() +{ + if( mVertexBuffer ) + { + mVertexBuffer->GlContextDestroyed(); + } + if( mIndexBuffer ) + { + mIndexBuffer->GlContextDestroyed(); + } +} + void TextRenderer::GlCleanup() { mVertexBuffer.Reset(); diff --git a/dali/internal/render/renderers/scene-graph-text-renderer.h b/dali/internal/render/renderers/scene-graph-text-renderer.h index 7f2c7b629..4fb06e75b 100644 --- a/dali/internal/render/renderers/scene-graph-text-renderer.h +++ b/dali/internal/render/renderers/scene-graph-text-renderer.h @@ -113,6 +113,11 @@ public: */ void SetSmoothEdge( float params ); + /** + * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed() + */ + virtual void GlContextDestroyed(); + /** * @copydoc Dali::Internal::GlResourceOwner::GlCleanup() */ diff --git a/dali/internal/render/shaders/program.h b/dali/internal/render/shaders/program.h index e55b80a7d..882195bd8 100644 --- a/dali/internal/render/shaders/program.h +++ b/dali/internal/render/shaders/program.h @@ -22,6 +22,7 @@ // INTERNAL INCLUDES #include +#include #include #include #include diff --git a/dali/internal/render/shaders/shader.cpp b/dali/internal/render/shaders/shader.cpp index 20ee00d01..f87832586 100644 --- a/dali/internal/render/shaders/shader.cpp +++ b/dali/internal/render/shaders/shader.cpp @@ -276,11 +276,6 @@ bool Shader::AreSubtypesRequired(GeometryType geometryType) return ! mPrograms[ programType ].mUseDefaultForAllSubtypes; } -void Shader::GlCleanup() -{ - mPrograms.clear(); -} - Program& Shader::Apply( Context& context, BufferIndex bufferIndex, GeometryType type, diff --git a/dali/internal/render/shaders/shader.h b/dali/internal/render/shaders/shader.h index da05de0a9..7245845d2 100644 --- a/dali/internal/render/shaders/shader.h +++ b/dali/internal/render/shaders/shader.h @@ -62,7 +62,7 @@ class TextureCache; * A base class for a collection of shader programs, to apply an effect to different geometry types. * This class is also the default shader so its easier to override default behaviour */ -class Shader : public PropertyOwner, public GlResourceOwner +class Shader : public PropertyOwner { public: @@ -275,12 +275,6 @@ public: */ bool AreSubtypesRequired(GeometryType geometryType); - /** - * This is called within RenderManager::Render, after the shader is detached from the scene-graph. - * @post The base class resets the program references in mPrograms - */ - void GlCleanup(); - /** * Applies the shader effect specific program and sets the common uniforms * @pre The shader has been initialized. diff --git a/dali/internal/update/common/discard-queue.cpp b/dali/internal/update/common/discard-queue.cpp index 9210cb508..05632861c 100644 --- a/dali/internal/update/common/discard-queue.cpp +++ b/dali/internal/update/common/discard-queue.cpp @@ -142,8 +142,7 @@ void DiscardQueue::Add( BufferIndex updateBufferIndex, Shader* shader ) { DALI_ASSERT_DEBUG( NULL != shader ); - // Send message to clean-up GL resources in the next Render - DoGlCleanup( updateBufferIndex, *shader, mRenderQueue ); + // Programs are cached for the lifetime of DALi so no need for GL cleanup for shader for now. // The GL resources will now be freed in frame N // The Update for frame N+1 may occur in parallel with the rendering of frame N diff --git a/dali/internal/update/modeling/scene-graph-mesh.cpp b/dali/internal/update/modeling/scene-graph-mesh.cpp index 1309fb379..90bfe7a60 100644 --- a/dali/internal/update/modeling/scene-graph-mesh.cpp +++ b/dali/internal/update/modeling/scene-graph-mesh.cpp @@ -161,12 +161,6 @@ void Mesh::BindBuffers(Context& context) } } -void Mesh::GlCleanup() -{ - mVertexBuffer = NULL; - mIndicesBuffer = NULL; -} - size_t Mesh::GetFaceIndexCount( ThreadBuffer threadBuffer ) const { DALI_ASSERT_DEBUG( threadBuffer == Mesh::RENDER_THREAD ); @@ -192,6 +186,24 @@ bool Mesh::HasGeometry( ThreadBuffer threadBuffer ) const return GetMeshData(threadBuffer).GetVertexCount() > 0; } +void Mesh::GlContextDestroyed() +{ + if( mVertexBuffer ) + { + mVertexBuffer->GlContextDestroyed(); + } + if( mIndicesBuffer ) + { + mIndicesBuffer->GlContextDestroyed(); + } +} + +void Mesh::GlCleanup() +{ + mVertexBuffer = NULL; + mIndicesBuffer = NULL; +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/update/modeling/scene-graph-mesh.h b/dali/internal/update/modeling/scene-graph-mesh.h index fd9bbd3aa..0f0e027ab 100644 --- a/dali/internal/update/modeling/scene-graph-mesh.h +++ b/dali/internal/update/modeling/scene-graph-mesh.h @@ -133,6 +133,18 @@ public: **/ bool HasGeometry( ThreadBuffer threadBuffer ) const; +public: // from GlResourceOwner + + /** + * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed() + */ + virtual void GlContextDestroyed(); + + /** + * @copydoc Dali::Internal::GlResourceOwner::GlCleanup() + */ + virtual void GlCleanup(); + private: /** @@ -148,13 +160,8 @@ private: // Undefined Mesh& operator=(const Mesh& rhs); - /** - * From GlResourceOwner - delete the GL texture. - * @pre This method is should only be called from the render-thread. - */ - virtual void GlCleanup(); - protected: + ResourceId mResourceId; /**