Add API for setting resource destruction callback
[platform/core/uifw/dali-adaptor.git] / dali / internal / imaging / tizen / native-image-source-impl-tizen.cpp
old mode 100755 (executable)
new mode 100644 (file)
index 987a357..f8e8f7c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 // EXTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/gl-defines.h>
-#include <cstring>
 #include <tbm_surface_internal.h>
+#include <cstring>
 
 // INTERNAL INCLUDES
+#include <dali/integration-api/adaptor-framework/render-surface-interface.h>
+#include <dali/internal/adaptor/common/adaptor-impl.h>
 #include <dali/internal/graphics/common/egl-image-extensions.h>
 #include <dali/internal/graphics/gles/egl-graphics.h>
-#include <dali/internal/adaptor/common/adaptor-impl.h>
-#include <dali/integration-api/render-surface.h>
-
-// Allow this to be encoded and saved:
-#include <dali/devel-api/adaptor-framework/bitmap-saver.h>
 
 namespace Dali
 {
-
 namespace Internal
 {
-
 namespace Adaptor
 {
-
 namespace
 {
-const char* FRAGMENT_PREFIX = "#extension GL_OES_EGL_image_external:require\n";
-const char* SAMPLER_TYPE = "samplerExternalOES";
+const char* SAMPLER_TYPE    = "samplerExternalOES";
 
+// clang-format off
 tbm_format FORMATS_BLENDING_REQUIRED[] = {
   TBM_FORMAT_ARGB4444, TBM_FORMAT_ABGR4444,
   TBM_FORMAT_RGBA4444, TBM_FORMAT_BGRA4444,
@@ -58,19 +52,20 @@ tbm_format FORMATS_BLENDING_REQUIRED[] = {
   TBM_FORMAT_ARGB2101010, TBM_FORMAT_ABGR2101010,
   TBM_FORMAT_RGBA1010102, TBM_FORMAT_BGRA1010102
 };
+// clang-format on
 
 const int NUM_FORMATS_BLENDING_REQUIRED = 18;
 
-}
+} // namespace
 
 using Dali::Integration::PixelBuffer;
 
-NativeImageSourceTizen* NativeImageSourceTizen::New( uint32_t width, uint32_t height, Dali::NativeImageSource::ColorDepth depth, Any nativeImageSource )
+NativeImageSourceTizen* NativeImageSourceTizen::New(uint32_t width, uint32_t height, Dali::NativeImageSource::ColorDepth depth, Any nativeImageSource)
 {
-  NativeImageSourceTizen* image = new NativeImageSourceTizen( width, height, depth, nativeImageSource );
-  DALI_ASSERT_DEBUG( image && "NativeImageSource allocation failed." );
+  NativeImageSourceTizen* image = new NativeImageSourceTizen(width, height, depth, nativeImageSource);
+  DALI_ASSERT_DEBUG(image && "NativeImageSource allocation failed.");
 
-  if( image )
+  if(image)
   {
     image->Initialize();
   }
@@ -78,81 +73,84 @@ NativeImageSourceTizen* NativeImageSourceTizen::New( uint32_t width, uint32_t he
   return image;
 }
 
-NativeImageSourceTizen::NativeImageSourceTizen( uint32_t width, uint32_t height, Dali::NativeImageSource::ColorDepth depth, Any nativeImageSource )
-: mWidth( width ),
-  mHeight( height ),
-  mOwnTbmSurface( false ),
-  mTbmSurface( NULL ),
-  mTbmFormat( 0 ),
-  mBlendingRequired( false ),
-  mColorDepth( depth ),
-  mEglImageKHR( NULL ),
-  mEglGraphics( NULL ),
-  mEglImageExtensions( NULL ),
-  mSetSource( false ),
-  mMutex()
+NativeImageSourceTizen::NativeImageSourceTizen(uint32_t width, uint32_t height, Dali::NativeImageSource::ColorDepth depth, Any nativeImageSource)
+: mWidth(width),
+  mHeight(height),
+  mOwnTbmSurface(false),
+  mTbmSurface(NULL),
+  mTbmFormat(0),
+  mBlendingRequired(false),
+  mColorDepth(depth),
+  mEglImageKHR(NULL),
+  mEglGraphics(NULL),
+  mEglImageExtensions(NULL),
+  mSetSource(false),
+  mMutex(),
+  mIsBufferAcquired(false),
+  mResourceDestructionCallback()
+
 {
-  DALI_ASSERT_ALWAYS( Adaptor::IsAvailable() );
+  DALI_ASSERT_ALWAYS(Adaptor::IsAvailable());
 
-  GraphicsInterface* graphics = &( Adaptor::GetImplementation( Adaptor::Get() ).GetGraphicsInterface() );
-  mEglGraphics = static_cast<EglGraphics *>(graphics);
+  GraphicsInterface* graphics = &(Adaptor::GetImplementation(Adaptor::Get()).GetGraphicsInterface());
+  mEglGraphics                = static_cast<EglGraphics*>(graphics);
 
-  mTbmSurface = GetSurfaceFromAny( nativeImageSource );
+  mTbmSurface = GetSurfaceFromAny(nativeImageSource);
 
-  if( mTbmSurface != NULL )
+  if(mTbmSurface != NULL)
   {
-    tbm_surface_internal_ref( mTbmSurface );
-    mBlendingRequired = CheckBlending( tbm_surface_get_format( mTbmSurface ) );
-    mWidth = tbm_surface_get_width( mTbmSurface );
-    mHeight = tbm_surface_get_height( mTbmSurface );
+    tbm_surface_internal_ref(mTbmSurface);
+    mBlendingRequired = CheckBlending(tbm_surface_get_format(mTbmSurface));
+    mWidth            = tbm_surface_get_width(mTbmSurface);
+    mHeight           = tbm_surface_get_height(mTbmSurface);
   }
 }
 
 void NativeImageSourceTizen::Initialize()
 {
-  if( mTbmSurface != NULL || mWidth == 0 || mHeight == 0 )
+  if(mTbmSurface != NULL || mWidth == 0 || mHeight == 0)
   {
     return;
   }
 
   tbm_format format = TBM_FORMAT_RGB888;
-  int depth = 0;
+  int        depth  = 0;
 
-  switch( mColorDepth )
+  switch(mColorDepth)
   {
     case Dali::NativeImageSource::COLOR_DEPTH_DEFAULT:
     {
-      format = TBM_FORMAT_RGBA8888;
-      depth = 32;
+      format = TBM_FORMAT_ARGB8888;
+      depth  = 32;
       break;
     }
     case Dali::NativeImageSource::COLOR_DEPTH_8:
     {
       format = TBM_FORMAT_C8;
-      depth = 8;
+      depth  = 8;
       break;
     }
     case Dali::NativeImageSource::COLOR_DEPTH_16:
     {
       format = TBM_FORMAT_RGB565;
-      depth = 16;
+      depth  = 16;
       break;
     }
     case Dali::NativeImageSource::COLOR_DEPTH_24:
     {
       format = TBM_FORMAT_RGB888;
-      depth = 24;
+      depth  = 24;
       break;
     }
     case Dali::NativeImageSource::COLOR_DEPTH_32:
     {
-      format = TBM_FORMAT_RGBA8888;
-      depth = 32;
+      format = TBM_FORMAT_ARGB8888;
+      depth  = 32;
       break;
     }
     default:
     {
-      DALI_LOG_WARNING( "Wrong color depth.\n" );
+      DALI_LOG_WARNING("Wrong color depth.\n");
       return;
     }
   }
@@ -162,22 +160,22 @@ void NativeImageSourceTizen::Initialize()
      If depth = 8, Pixel::A8;
      If depth = 16, Pixel::RGB565;
      If depth = 32, Pixel::RGBA8888 */
-  mBlendingRequired = ( depth == 32 || depth == 8 );
+  mBlendingRequired = (depth == 32 || depth == 8);
 
-  mTbmSurface = tbm_surface_create( mWidth, mHeight, format );
+  mTbmSurface    = tbm_surface_create(mWidth, mHeight, format);
   mOwnTbmSurface = true;
 }
 
-tbm_surface_h NativeImageSourceTizen::GetSurfaceFromAny( Any source ) const
+tbm_surface_h NativeImageSourceTizen::GetSurfaceFromAny(Any source) const
 {
-  if( source.Empty() )
+  if(source.Empty())
   {
     return NULL;
   }
 
-  if( source.GetType() == typeid( tbm_surface_h ) )
+  if(source.GetType() == typeid(tbm_surface_h))
   {
-    return AnyCast< tbm_surface_h >( source );
+    return AnyCast<tbm_surface_h>(source);
   }
   else
   {
@@ -185,181 +183,183 @@ tbm_surface_h NativeImageSourceTizen::GetSurfaceFromAny( Any source ) const
   }
 }
 
-NativeImageSourceTizen::~NativeImageSourceTizen()
+void NativeImageSourceTizen::DestroySurface()
 {
-  if( mOwnTbmSurface )
+  if(mTbmSurface)
   {
-    if( mTbmSurface != NULL && tbm_surface_destroy( mTbmSurface ) != TBM_SURFACE_ERROR_NONE )
+    if(mIsBufferAcquired)
     {
-      DALI_LOG_ERROR( "Failed to destroy tbm_surface\n" );
+      ReleaseBuffer();
     }
-  }
-  else
-  {
-    if( mTbmSurface != NULL )
+    if(mOwnTbmSurface)
+    {
+      if(tbm_surface_destroy(mTbmSurface) != TBM_SURFACE_ERROR_NONE)
+      {
+        DALI_LOG_ERROR("Failed to destroy tbm_surface\n");
+      }
+    }
+    else
     {
-      tbm_surface_internal_unref( mTbmSurface );
+      tbm_surface_internal_unref(mTbmSurface);
     }
   }
 }
 
+NativeImageSourceTizen::~NativeImageSourceTizen()
+{
+  DestroySurface();
+}
+
 Any NativeImageSourceTizen::GetNativeImageSource() const
 {
-  return Any( mTbmSurface );
+  return Any(mTbmSurface);
 }
 
 bool NativeImageSourceTizen::GetPixels(std::vector<unsigned char>& pixbuf, unsigned& width, unsigned& height, Pixel::Format& pixelFormat) const
 {
-  Dali::Mutex::ScopedLock lock( mMutex );
-  if( mTbmSurface != NULL )
+  Dali::Mutex::ScopedLock lock(mMutex);
+  if(mTbmSurface != NULL)
   {
     tbm_surface_info_s surface_info;
 
-    if( tbm_surface_map( mTbmSurface, TBM_SURF_OPTION_READ, &surface_info) != TBM_SURFACE_ERROR_NONE )
+    if(tbm_surface_map(mTbmSurface, TBM_SURF_OPTION_READ, &surface_info) != TBM_SURFACE_ERROR_NONE)
     {
-      DALI_LOG_ERROR( "Fail to map tbm_surface\n" );
+      DALI_LOG_ERROR("Fail to map tbm_surface\n");
 
-      width = 0;
+      width  = 0;
       height = 0;
 
       return false;
     }
 
-    tbm_format format = surface_info.format;
-    uint32_t stride = surface_info.planes[0].stride;
-    unsigned char* ptr = surface_info.planes[0].ptr;
+    tbm_format     format = surface_info.format;
+    uint32_t       stride = surface_info.planes[0].stride;
+    unsigned char* ptr    = surface_info.planes[0].ptr;
 
-    width = mWidth;
+    width  = mWidth;
     height = mHeight;
     size_t lineSize;
     size_t offset;
     size_t cOffset;
 
-    switch( format )
+    switch(format)
     {
       case TBM_FORMAT_RGB888:
       {
-        lineSize = width*3;
+        lineSize    = width * 3;
         pixelFormat = Pixel::RGB888;
-        pixbuf.resize( lineSize*height );
+        pixbuf.resize(lineSize * height);
         unsigned char* bufptr = &pixbuf[0];
 
-        for( unsigned int r = 0; r < height; ++r, bufptr += lineSize )
+        for(unsigned int r = 0; r < height; ++r, bufptr += lineSize)
         {
-          for( unsigned int c = 0; c < width; ++c )
+          for(unsigned int c = 0; c < width; ++c)
           {
-            cOffset = c*3;
-            offset = cOffset + r*stride;
-            *(bufptr+cOffset) = ptr[offset+2];
-            *(bufptr+cOffset+1) = ptr[offset+1];
-            *(bufptr+cOffset+2) = ptr[offset];
+            cOffset                 = c * 3;
+            offset                  = cOffset + r * stride;
+            *(bufptr + cOffset)     = ptr[offset + 2];
+            *(bufptr + cOffset + 1) = ptr[offset + 1];
+            *(bufptr + cOffset + 2) = ptr[offset];
           }
         }
         break;
       }
       case TBM_FORMAT_RGBA8888:
       {
-        lineSize = width*4;
+        lineSize    = width * 4;
         pixelFormat = Pixel::RGBA8888;
-        pixbuf.resize( lineSize*height );
+        pixbuf.resize(lineSize * height);
         unsigned char* bufptr = &pixbuf[0];
 
-        for( unsigned int r = 0; r < height; ++r, bufptr += lineSize )
+        for(unsigned int r = 0; r < height; ++r, bufptr += lineSize)
         {
-          for( unsigned int c = 0; c < width; ++c )
+          for(unsigned int c = 0; c < width; ++c)
           {
-            cOffset = c*4;
-            offset = cOffset + r*stride;
-            *(bufptr+cOffset) = ptr[offset+3];
-            *(bufptr+cOffset+1) = ptr[offset+2];
-            *(bufptr+cOffset+2) = ptr[offset+1];
-            *(bufptr+cOffset+3) = ptr[offset];
+            cOffset                 = c * 4;
+            offset                  = cOffset + r * stride;
+            *(bufptr + cOffset)     = ptr[offset + 3];
+            *(bufptr + cOffset + 1) = ptr[offset + 2];
+            *(bufptr + cOffset + 2) = ptr[offset + 1];
+            *(bufptr + cOffset + 3) = ptr[offset];
+          }
+        }
+        break;
+      }
+      case TBM_FORMAT_ARGB8888:
+      {
+        lineSize    = width * 4;
+        pixelFormat = Pixel::RGBA8888;
+        pixbuf.resize(lineSize * height);
+        unsigned char* bufptr = &pixbuf[0];
+
+        for(unsigned int r = 0; r < height; ++r, bufptr += lineSize)
+        {
+          for(unsigned int c = 0; c < width; ++c)
+          {
+            cOffset                 = c * 4;
+            offset                  = cOffset + r * stride;
+            *(bufptr + cOffset)     = ptr[offset + 2];
+            *(bufptr + cOffset + 1) = ptr[offset + 1];
+            *(bufptr + cOffset + 2) = ptr[offset];
+            *(bufptr + cOffset + 3) = ptr[offset + 3];
           }
         }
         break;
       }
       default:
       {
-        DALI_ASSERT_ALWAYS( 0 && "Tbm surface has unsupported pixel format.\n" );
+        DALI_ASSERT_ALWAYS(0 && "Tbm surface has unsupported pixel format.\n");
 
         return false;
       }
     }
 
-    if( tbm_surface_unmap( mTbmSurface ) != TBM_SURFACE_ERROR_NONE )
+    if(tbm_surface_unmap(mTbmSurface) != TBM_SURFACE_ERROR_NONE)
     {
-      DALI_LOG_ERROR( "Fail to unmap tbm_surface\n" );
+      DALI_LOG_ERROR("Fail to unmap tbm_surface\n");
     }
 
     return true;
   }
 
-  DALI_LOG_WARNING( "TBM surface does not exist.\n" );
+  DALI_LOG_WARNING("TBM surface does not exist.\n");
 
-  width = 0;
+  width  = 0;
   height = 0;
 
   return false;
 }
 
-bool NativeImageSourceTizen::EncodeToFile(const std::string& filename) const
+void NativeImageSourceTizen::SetSource(Any source)
 {
-  std::vector< unsigned char > pixbuf;
-  unsigned int width(0), height(0);
-  Pixel::Format pixelFormat;
+  Dali::Mutex::ScopedLock lock(mMutex);
 
-  if(GetPixels(pixbuf, width, height, pixelFormat))
-  {
-    return Dali::EncodeToFile(&pixbuf[0], filename, pixelFormat, width, height);
-  }
-  return false;
-}
+  DestroySurface();
 
-void NativeImageSourceTizen::SetSource( Any source )
-{
-  Dali::Mutex::ScopedLock lock( mMutex );
-  if( mOwnTbmSurface )
-  {
-    if( mTbmSurface != NULL && tbm_surface_destroy( mTbmSurface ) != TBM_SURFACE_ERROR_NONE )
-    {
-      DALI_LOG_ERROR( "Failed to destroy tbm_surface\n" );
-    }
+  mOwnTbmSurface = false;
+  mTbmSurface    = GetSurfaceFromAny(source);
 
-    mTbmSurface = NULL;
-    mOwnTbmSurface = false;
-  }
-  else
-  {
-    if( mTbmSurface != NULL )
-    {
-      tbm_surface_internal_unref( mTbmSurface );
-      mTbmSurface = NULL;
-    }
-  }
-
-  mTbmSurface = GetSurfaceFromAny( source );
-
-  if( mTbmSurface != NULL )
+  if(mTbmSurface != NULL)
   {
     mSetSource = true;
-    tbm_surface_internal_ref( mTbmSurface );
-    mBlendingRequired = CheckBlending( tbm_surface_get_format( mTbmSurface ) );
-    mWidth = tbm_surface_get_width( mTbmSurface );
-    mHeight = tbm_surface_get_height( mTbmSurface );
+    tbm_surface_internal_ref(mTbmSurface);
+    mBlendingRequired = CheckBlending(tbm_surface_get_format(mTbmSurface));
+    mWidth            = tbm_surface_get_width(mTbmSurface);
+    mHeight           = tbm_surface_get_height(mTbmSurface);
   }
 }
 
-bool NativeImageSourceTizen::IsColorDepthSupported( Dali::NativeImageSource::ColorDepth colorDepth )
+bool NativeImageSourceTizen::IsColorDepthSupported(Dali::NativeImageSource::ColorDepth colorDepth)
 {
-  uint32_t* formats;
-  uint32_t formatNum;
+  uint32_t*  formats;
+  uint32_t   formatNum;
   tbm_format format = TBM_FORMAT_RGB888;
 
-  switch( colorDepth )
+  switch(colorDepth)
   {
     case Dali::NativeImageSource::COLOR_DEPTH_DEFAULT:
     {
-      format = TBM_FORMAT_RGBA8888;
+      format = TBM_FORMAT_ARGB8888;
       break;
     }
     case Dali::NativeImageSource::COLOR_DEPTH_8:
@@ -379,54 +379,65 @@ bool NativeImageSourceTizen::IsColorDepthSupported( Dali::NativeImageSource::Col
     }
     case Dali::NativeImageSource::COLOR_DEPTH_32:
     {
-      format = TBM_FORMAT_RGBA8888;
+      format = TBM_FORMAT_ARGB8888;
       break;
     }
   }
 
-  if( tbm_surface_query_formats( &formats, &formatNum ) )
+  if(tbm_surface_query_formats(&formats, &formatNum))
   {
-    for( unsigned int i = 0; i < formatNum; i++ )
+    for(unsigned int i = 0; i < formatNum; i++)
     {
-      if( formats[i] == format )
+      if(formats[i] == format)
       {
-        free( formats );
+        free(formats);
         return true;
       }
     }
   }
 
-  free( formats );
+  free(formats);
   return false;
 }
 
-bool NativeImageSourceTizen::GlExtensionCreate()
+bool NativeImageSourceTizen::CreateResource()
 {
+  // If an EGL image exists, use it as it is without creating it.
+  if(mEglImageKHR != NULL)
+  {
+    return true;
+  }
+
   // casting from an unsigned int to a void *, which should then be cast back
   // to an unsigned int in the driver.
-  EGLClientBuffer eglBuffer = reinterpret_cast< EGLClientBuffer >(mTbmSurface);
-  if( !eglBuffer || !tbm_surface_internal_is_valid( mTbmSurface ) )
+  EGLClientBuffer eglBuffer = reinterpret_cast<EGLClientBuffer>(mTbmSurface);
+  if(!eglBuffer || !tbm_surface_internal_is_valid(mTbmSurface))
   {
     return false;
   }
 
   mEglImageExtensions = mEglGraphics->GetImageExtensions();
-  DALI_ASSERT_DEBUG( mEglImageExtensions );
+  DALI_ASSERT_DEBUG(mEglImageExtensions);
 
-  mEglImageKHR = mEglImageExtensions->CreateImageKHR( eglBuffer );
+  mEglImageKHR = mEglImageExtensions->CreateImageKHR(eglBuffer);
 
   return mEglImageKHR != NULL;
 }
 
-void NativeImageSourceTizen::GlExtensionDestroy()
+void NativeImageSourceTizen::DestroyResource()
 {
-  Dali::Mutex::ScopedLock lock( mMutex );
-  if( mEglImageKHR )
+  Dali::Mutex::ScopedLock lock(mMutex);
+  if(mEglImageKHR)
   {
     mEglImageExtensions->DestroyImageKHR(mEglImageKHR);
 
     mEglImageKHR = NULL;
   }
+
+  if(mResourceDestructionCallback)
+  {
+    mResourceDestructionCallback->Trigger();
+  }
 }
 
 uint32_t NativeImageSourceTizen::TargetTexture()
@@ -438,44 +449,55 @@ uint32_t NativeImageSourceTizen::TargetTexture()
 
 void NativeImageSourceTizen::PrepareTexture()
 {
-  Dali::Mutex::ScopedLock lock( mMutex );
-  if( mSetSource )
+  Dali::Mutex::ScopedLock lock(mMutex);
+  if(mSetSource)
   {
-    void* eglImage = mEglImageKHR;
+    // Destroy previous eglImage because use for new one.
+    // if mEglImageKHR is not to be NULL here, it will not be updated with a new eglImage.
+    mEglImageExtensions->DestroyImageKHR(mEglImageKHR);
+    mEglImageKHR = NULL;
 
-    if( GlExtensionCreate() )
+    if(CreateResource())
     {
       TargetTexture();
     }
 
-    mEglImageExtensions->DestroyImageKHR( eglImage );
-
     mSetSource = false;
   }
 }
 
-const char* NativeImageSourceTizen::GetCustomFragmentPreFix()
+bool NativeImageSourceTizen::ApplyNativeFragmentShader(std::string& shader)
 {
-  return FRAGMENT_PREFIX;
+  return mEglGraphics->ApplyNativeFragmentShader(shader, SAMPLER_TYPE);
 }
 
-const char* NativeImageSourceTizen::GetCustomSamplerTypename()
+const char* NativeImageSourceTizen::GetCustomSamplerTypename() const
 {
   return SAMPLER_TYPE;
 }
 
-int NativeImageSourceTizen::GetEglImageTextureTarget()
+int NativeImageSourceTizen::GetTextureTarget() const
 {
   return GL_TEXTURE_EXTERNAL_OES;
 }
 
-bool NativeImageSourceTizen::CheckBlending( tbm_format format )
+Any NativeImageSourceTizen::GetNativeImageHandle() const
+{
+  return GetNativeImageSource();
+}
+
+bool NativeImageSourceTizen::SourceChanged() const
 {
-  if( mTbmFormat != format )
+  return false;
+}
+
+bool NativeImageSourceTizen::CheckBlending(tbm_format format)
+{
+  if(mTbmFormat != format)
   {
     for(int i = 0; i < NUM_FORMATS_BLENDING_REQUIRED; ++i)
     {
-      if( format == FORMATS_BLENDING_REQUIRED[i] )
+      if(format == FORMATS_BLENDING_REQUIRED[i])
       {
         mBlendingRequired = true;
         break;
@@ -487,8 +509,58 @@ bool NativeImageSourceTizen::CheckBlending( tbm_format format )
   return mBlendingRequired;
 }
 
+uint8_t* NativeImageSourceTizen::AcquireBuffer(uint16_t& width, uint16_t& height, uint16_t& stride)
+{
+  Dali::Mutex::ScopedLock lock(mMutex);
+  if(mTbmSurface != NULL)
+  {
+    tbm_surface_info_s info;
+
+    if(tbm_surface_map(mTbmSurface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &info) != TBM_SURFACE_ERROR_NONE)
+    {
+      DALI_LOG_ERROR("Fail to map tbm_surface\n");
+
+      width  = 0;
+      height = 0;
+
+      return NULL;
+    }
+    tbm_surface_internal_ref(mTbmSurface);
+    mIsBufferAcquired = true;
+
+    stride = info.planes[0].stride;
+    width  = mWidth;
+    height = mHeight;
+
+    return info.planes[0].ptr;
+  }
+  return NULL;
+}
+
+bool NativeImageSourceTizen::ReleaseBuffer()
+{
+  Dali::Mutex::ScopedLock lock(mMutex);
+  bool                    ret = false;
+  if(mTbmSurface != NULL)
+  {
+    ret = (tbm_surface_unmap(mTbmSurface) == TBM_SURFACE_ERROR_NONE);
+    if(!ret)
+    {
+      DALI_LOG_ERROR("Fail to unmap tbm_surface\n");
+    }
+    tbm_surface_internal_unref(mTbmSurface);
+    mIsBufferAcquired = false;
+  }
+  return ret;
+}
+
+void NativeImageSourceTizen::SetResourceDestructionCallback(EventThreadCallback* callback)
+{
+  mResourceDestructionCallback = std::unique_ptr<EventThreadCallback>(callback);
+}
+
 } // namespace Adaptor
 
-} // namespace internal
+} // namespace Internal
 
 } // namespace Dali