ContextObserver removal, part II: Its gone 25/20625/1
authorKimmo Hoikka <kimmo.hoikka@samsung.com>
Tue, 6 May 2014 12:50:23 +0000 (13:50 +0100)
committerFerran Sole <ferran.sole@samsung.com>
Fri, 9 May 2014 14:02:24 +0000 (15:02 +0100)
[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 <ferran.sole@samsung.com>
25 files changed:
dali/internal/common/core-impl.cpp
dali/internal/render/common/render-manager.cpp
dali/internal/render/common/render-manager.h
dali/internal/render/gl-resources/context-observer.h [deleted file]
dali/internal/render/gl-resources/context.cpp
dali/internal/render/gl-resources/context.h
dali/internal/render/gl-resources/gl-resource-owner.h
dali/internal/render/gl-resources/gpu-buffer.cpp
dali/internal/render/gl-resources/gpu-buffer.h
dali/internal/render/gl-resources/texture-cache.cpp
dali/internal/render/gl-resources/texture-cache.h
dali/internal/render/gl-resources/texture.cpp
dali/internal/render/gl-resources/texture.h
dali/internal/render/renderers/scene-graph-image-renderer.cpp
dali/internal/render/renderers/scene-graph-image-renderer.h
dali/internal/render/renderers/scene-graph-mesh-renderer.cpp
dali/internal/render/renderers/scene-graph-mesh-renderer.h
dali/internal/render/renderers/scene-graph-text-renderer.cpp
dali/internal/render/renderers/scene-graph-text-renderer.h
dali/internal/render/shaders/program.h
dali/internal/render/shaders/shader.cpp
dali/internal/render/shaders/shader.h
dali/internal/update/common/discard-queue.cpp
dali/internal/update/modeling/scene-graph-mesh.cpp
dali/internal/update/modeling/scene-graph-mesh.h

index 443894200c520acd9e4a5d732174975ec1488fec..1fedc18e85d5a4a777bd816e6f6d93bb4e85da80 100644 (file)
@@ -211,7 +211,7 @@ void Core::ContextCreated()
 
 void Core::ContextToBeDestroyed()
 {
-  mRenderManager->ContextToBeDestroyed();
+  mRenderManager->ContextDestroyed();
 }
 
 void Core::SurfaceResized(unsigned int width, unsigned int height)
index 23ee5b40af8fceef6d93ce02d2b3f0c9383f2803..092df858e72fd4c6084b483109ad23dc97be987a 100644 (file)
@@ -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<int>                           mDefaultSurfaceRect; ///< Rectangle for the default surface we are rendering to
+  Rect<int>                           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<int>& 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;
     }
   }
 
index 6d080a52d99ac62e37dfd94c20b88b3d908a949b..33dc702cad427c41f39f7cec8e6e3fa14c01d72f 100644 (file)
@@ -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 (file)
index 35ae0dc..0000000
+++ /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__
index 1ba14530698c6d7dea92bf7e7d627011ffa9a5c3..9dd2f68fc06e20efb007846844d75f54738750f4 100644 (file)
@@ -23,7 +23,6 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/common/constants.h>
-#include <dali/internal/render/gl-resources/context-observer.h>
 #include <dali/internal/render/shaders/program.h>
 #include <dali/integration-api/platform-abstraction.h>
 #include <dali/internal/render/common/render-manager.h>
@@ -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<ContextObserver*>::iterator end = mObservers.end();
-  for ( std::set<ContextObserver*>::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<ContextObserver*>::iterator end = mObservers.end();
-  for ( std::set<ContextObserver*>::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)
index 2517b0cbe420d23746e4788c9de70a07d741b06e..a737f347a0f844c5329362b5bb06616b6402f5c2 100644 (file)
@@ -19,7 +19,6 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/common/map-wrapper.h>
-#include <dali/public-api/common/set-wrapper.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/actors/renderable-actor.h>
 #include <dali/integration-api/debug.h>
@@ -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<ContextObserver*> mObservers;
-
   Program* mCurrentProgram;
   typedef std::map< std::size_t, Program* > ProgramContainer;
   ProgramContainer mProgramCache; /// program cache
index fdf9e089c5e614f180fc4ae8950f87868c28c3a5..5600a661c556361528fb3e2486d6de919e13d721 100644 (file)
@@ -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
index bdbc2f956562af058d14eceb96cf12ccfc01c0fc..40564e2884a42cb5c725f94c1c350b4212c15f19 100644 (file)
@@ -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;
index ea37380c5c33c5dd57f0b12672b5e5f4198837e7..baf3c059fd9559d8be7ad3f66d445e10aa4a0747 100644 (file)
@@ -19,7 +19,6 @@
 
 // INTERNAL INCLUDES
 #include <dali/internal/render/gl-resources/context.h>
-#include <dali/internal/render/gl-resources/context-observer.h>
 
 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:
 
index b2726c1646e75fa8500dea4fb4cdcf089341638b..c06fc0ab232448ac784da20194cf9a1c581b345b 100644 (file)
@@ -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  *********************
  ********************************************************************************/
index 686fcfbf583b103770e43d93b3b1c6a6bdaa1e21..ab132d7047d70732362c5bf368015d051da992c2 100644 (file)
@@ -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
 
   /**
index aac69f481fc458a23c906d1935ce3a9da0935fad..f5b3933b79e42c49b996c8f3dc112dbeb14d6c0a 100644 (file)
@@ -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 )
index 4d6ae1e288cca5b1865998dd1f14d0e32b6e19f0..f22e382b8506998b9fc16f532f3e518a85722ae0 100644 (file)
@@ -20,7 +20,6 @@
 // INTERNAL INCLUDES
 #include <dali/public-api/object/ref-object.h>
 #include <dali/integration-api/bitmap.h>
-#include <dali/internal/render/gl-resources/context-observer.h>
 #include <dali/internal/render/common/uv-rect.h>
 #include <dali/integration-api/gl-abstraction.h>
 #include <dali/internal/render/gl-resources/gl-resource-owner.h>
@@ -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();
 
index fd100909433115ec3a9fe952c6b5f9a5e39aa87b..44699c82ad15c3c3787ef5986e4dcb9c17927822 100644 (file)
@@ -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
index 2eb6f542cbee03e5a2dbe22607078c4c153a36eb..c08fb1aa82113f000243b8aed09185bef0ee6d72 100644 (file)
@@ -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()
    */
index e5c40fc4e2b7099fc42310fa2669fa5730a490d0..bbed49c560d9abc12affea36158fb61b70810a71 100644 (file)
@@ -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
index 0a59f7b7ab02df5fd1806c79af87d123a3d4a8a4..dc91a63f0d77e29362abb1590bd69024932938e9 100644 (file)
@@ -99,6 +99,11 @@ public:
 
 private:
 
+  /**
+   * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed()
+   */
+  virtual void GlContextDestroyed();
+
   /**
    * @copydoc Dali::Internal::GlResourceOwner::GlCleanup()
    */
index 38a5396e6def9c8dbafa4c8cce90a84cf37add09..18cc3da70182294e81a956770012760710a0c75e 100644 (file)
@@ -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();
index 7f2c7b6299561c586bc315ca4e5a20553f78b973..4fb06e75b4ea2649b3a056eff948f22e5eeb833b 100644 (file)
@@ -113,6 +113,11 @@ public:
    */
   void SetSmoothEdge( float params );
 
+  /**
+   * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed()
+   */
+  virtual void GlContextDestroyed();
+
   /**
    * @copydoc Dali::Internal::GlResourceOwner::GlCleanup()
    */
index e55b80a7df5e7eecccf6aa88217fce6a72308caa..882195bd8978afc6c4943d8be6aa09c7d426f112 100644 (file)
@@ -22,6 +22,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/common/set-wrapper.h>
 #include <dali/public-api/object/ref-object.h>
 #include <dali/internal/render/gl-resources/context.h>
 #include <dali/integration-api/resource-cache.h>
index 20ee00d01718a2c112d8f732f1125e65683de277..f878325866f56d2afef46043fdbc0db4e92080a7 100644 (file)
@@ -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,
index da05de0a9d20bd78f8ec1dd44edae1ff944de739..7245845d293bf62c855ff11905963d6b446f9e16 100644 (file)
@@ -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.
index 9210cb5081ffc131779047dc4f64c9b26193ddb1..05632861c7cbfb338d006b8f072c947075df2720 100644 (file)
@@ -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
index 1309fb3799f0bf3506cd17faa4eca32075dd0c2b..90bfe7a60b401580aa8264d080dc71277312488f 100644 (file)
@@ -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
index fd9bbd3aaea2ff94c496cf2ec449e78d214ffe5a..0f0e027ab449c6eab01a94f5012a1023cd9708a1 100644 (file)
@@ -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;
 
   /**