void Core::ContextToBeDestroyed()
{
- mRenderManager->ContextToBeDestroyed();
+ mRenderManager->ContextDestroyed();
}
void Core::SurfaceResized(unsigned int width, unsigned int height)
dynamicsDebugRenderer( NULL ),
frameCount( 0 ),
renderBufferIndex( SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX ),
- mDefaultSurfaceRect(),
- mRendererContainer(),
- mMaterials(),
- mRenderersAdded( false )
+ defaultSurfaceRect(),
+ rendererContainer(),
+ materials(),
+ renderersAdded( false )
{
}
}
// 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
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
};
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)
void RenderManager::SetDefaultSurfaceRect(const Rect<int>& rect)
{
- mImpl->mDefaultSurfaceRect = rect;
+ mImpl->defaultSurfaceRect = rect;
}
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;
}
}
{
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 )
{
DALI_ASSERT_DEBUG( NULL != renderMaterial );
- mImpl->mMaterials.PushBack( renderMaterial );
+ mImpl->materials.PushBack( renderMaterial );
renderMaterial->Initialize( mImpl->textureCache );
}
{
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 )
{
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
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,
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;
}
}
/**
* @copydoc Dali::Integration::Core::ContextToBeDestroyed()
*/
- void ContextToBeDestroyed();
+ void ContextDestroyed();
/**
* Dispatch requests onto the postProcessResourcesQueue
+++ /dev/null
-#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__
// 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>
// release the cached programs
std::for_each(mProgramCache.begin(), mProgramCache.end(), deletePrograms);
mProgramCache.clear();
-
- DALI_ASSERT_DEBUG(mObservers.empty());
}
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 )
{
}
}
-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 )
{
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)
// 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>
namespace Internal
{
-class ContextObserver;
class Program; // to be able to cache programs
// wrap gl calls with CHECK_GL eg "CHECK_GL( *this, glBindTexture(textureId) );"
/**
* 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
/**
* 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.
*/
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
*/
*/
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.
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
* 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
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);
+ }
}
/*
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;
// INTERNAL INCLUDES
#include <dali/internal/render/gl-resources/context.h>
-#include <dali/internal/render/gl-resources/context-observer.h>
namespace Dali
{
* 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:
*/
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
};
GpuBuffer( Context& context, Target target, Usage usage );
/**
- * Destructor
+ * Destructor, non virtual as no virtual methods or inheritance
*/
- virtual ~GpuBuffer();
+ ~GpuBuffer();
/**
*
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:
}
}
+void TextureCache::GlContextDestroyed()
+{
+ TextureIter end = mTextures.end();
+ TextureIter iter = mTextures.begin();
+ for( ; iter != end; ++iter )
+ {
+ (*iter->second).GlContextDestroyed(); // map holds intrusive pointers
+ }
+}
+
/********************************************************************************
********************** Implements TextureCacheDispatcher *********************
********************************************************************************/
*/
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
/**
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)
}
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);
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 )
// 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>
* Texture class.
*/
class Texture: public RefObject,
- public ContextObserver,
public GlResourceOwner
{
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:
/**
* @return true on success
*/
virtual bool CreateGlTexture() = 0;
+
public:
/**
* Destructor.
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();
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
*/
void CalculateMeshData( MeshType type, const Vector2& targetSize, bool usePixelArea );
+ /**
+ * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed()
+ */
+ virtual void GlContextDestroyed();
+
/**
* @copydoc Dali::Internal::GlResourceOwner::GlCleanup()
*/
{
}
+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
private:
+ /**
+ * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed()
+ */
+ virtual void GlContextDestroyed();
+
/**
* @copydoc Dali::Internal::GlResourceOwner::GlCleanup()
*/
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();
*/
void SetSmoothEdge( float params );
+ /**
+ * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed()
+ */
+ virtual void GlContextDestroyed();
+
/**
* @copydoc Dali::Internal::GlResourceOwner::GlCleanup()
*/
// 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>
return ! mPrograms[ programType ].mUseDefaultForAllSubtypes;
}
-void Shader::GlCleanup()
-{
- mPrograms.clear();
-}
-
Program& Shader::Apply( Context& context,
BufferIndex bufferIndex,
GeometryType type,
* 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:
*/
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.
{
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
}
}
-void Mesh::GlCleanup()
-{
- mVertexBuffer = NULL;
- mIndicesBuffer = NULL;
-}
-
size_t Mesh::GetFaceIndexCount( ThreadBuffer threadBuffer ) const
{
DALI_ASSERT_DEBUG( threadBuffer == Mesh::RENDER_THREAD );
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
**/
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:
/**
// 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;
/**