[Tizen] 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 100644 (file)
new mode 100755 (executable)
index d4f77d9..3cd6831
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
 
 // INTERNAL INCLUDES
 #include <dali/internal/graphics/common/egl-image-extensions.h>
-#include <dali/internal/graphics/gles20/egl-factory.h>
+#include <dali/internal/graphics/gles/egl-graphics.h>
 #include <dali/internal/adaptor/common/adaptor-impl.h>
-#include <dali/devel-api/adaptor-framework/render-surface.h>
-
-// Allow this to be encoded and saved:
-#include <dali/devel-api/adaptor-framework/bitmap-saver.h>
+#include <dali/integration-api/adaptor-framework/render-surface-interface.h>
 
 namespace Dali
 {
@@ -65,7 +62,7 @@ const int NUM_FORMATS_BLENDING_REQUIRED = 18;
 
 using Dali::Integration::PixelBuffer;
 
-NativeImageSourceTizen* NativeImageSourceTizen::New(unsigned int width, unsigned int 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." );
@@ -78,7 +75,7 @@ NativeImageSourceTizen* NativeImageSourceTizen::New(unsigned int width, unsigned
   return image;
 }
 
-NativeImageSourceTizen::NativeImageSourceTizen( unsigned int width, unsigned int height, Dali::NativeImageSource::ColorDepth depth, Any nativeImageSource )
+NativeImageSourceTizen::NativeImageSourceTizen( uint32_t width, uint32_t height, Dali::NativeImageSource::ColorDepth depth, Any nativeImageSource )
 : mWidth( width ),
   mHeight( height ),
   mOwnTbmSurface( false ),
@@ -87,13 +84,17 @@ NativeImageSourceTizen::NativeImageSourceTizen( unsigned int width, unsigned int
   mBlendingRequired( false ),
   mColorDepth( depth ),
   mEglImageKHR( NULL ),
+  mEglGraphics( NULL ),
   mEglImageExtensions( NULL ),
-  mSetSource( false )
+  mSetSource( false ),
+  mMutex(),
+  mIsBufferAcquired( false ),
+  mResourceDestructionCallback()
 {
   DALI_ASSERT_ALWAYS( Adaptor::IsAvailable() );
-  EglFactory& eglFactory = Adaptor::GetImplementation( Adaptor::Get() ).GetEGLFactory();
-  mEglImageExtensions = eglFactory.GetImageExtensions();
-  DALI_ASSERT_DEBUG( mEglImageExtensions );
+
+  GraphicsInterface* graphics = &( Adaptor::GetImplementation( Adaptor::Get() ).GetGraphicsInterface() );
+  mEglGraphics = static_cast<EglGraphics *>(graphics);
 
   mTbmSurface = GetSurfaceFromAny( nativeImageSource );
 
@@ -120,7 +121,7 @@ void NativeImageSourceTizen::Initialize()
   {
     case Dali::NativeImageSource::COLOR_DEPTH_DEFAULT:
     {
-      format = TBM_FORMAT_RGBA8888;
+      format = TBM_FORMAT_ARGB8888;
       depth = 32;
       break;
     }
@@ -144,7 +145,7 @@ void NativeImageSourceTizen::Initialize()
     }
     case Dali::NativeImageSource::COLOR_DEPTH_32:
     {
-      format = TBM_FORMAT_RGBA8888;
+      format = TBM_FORMAT_ARGB8888;
       depth = 32;
       break;
     }
@@ -183,24 +184,33 @@ 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 );
     }
   }
 }
 
+NativeImageSourceTizen::~NativeImageSourceTizen()
+{
+  DestroySurface();
+}
+
 Any NativeImageSourceTizen::GetNativeImageSource() const
 {
   return Any( mTbmSurface );
@@ -208,6 +218,7 @@ Any NativeImageSourceTizen::GetNativeImageSource() const
 
 bool NativeImageSourceTizen::GetPixels(std::vector<unsigned char>& pixbuf, unsigned& width, unsigned& height, Pixel::Format& pixelFormat) const
 {
+  Dali::Mutex::ScopedLock lock( mMutex );
   if( mTbmSurface != NULL )
   {
     tbm_surface_info_s surface_info;
@@ -275,6 +286,27 @@ bool NativeImageSourceTizen::GetPixels(std::vector<unsigned char>& pixbuf, unsig
         }
         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" );
@@ -299,40 +331,13 @@ bool NativeImageSourceTizen::GetPixels(std::vector<unsigned char>& pixbuf, unsig
   return false;
 }
 
-bool NativeImageSourceTizen::EncodeToFile(const std::string& filename) const
-{
-  std::vector< unsigned char > pixbuf;
-  unsigned int width(0), height(0);
-  Pixel::Format pixelFormat;
-
-  if(GetPixels(pixbuf, width, height, pixelFormat))
-  {
-    return Dali::EncodeToFile(&pixbuf[0], filename, pixelFormat, width, height);
-  }
-  return false;
-}
-
 void NativeImageSourceTizen::SetSource( Any source )
 {
-  if( mOwnTbmSurface )
-  {
-    if( mTbmSurface != NULL && tbm_surface_destroy( mTbmSurface ) != TBM_SURFACE_ERROR_NONE )
-    {
-      DALI_LOG_ERROR( "Failed to destroy tbm_surface\n" );
-    }
+  Dali::Mutex::ScopedLock lock( mMutex );
 
-    mTbmSurface = NULL;
-    mOwnTbmSurface = false;
-  }
-  else
-  {
-    if( mTbmSurface != NULL )
-    {
-      tbm_surface_internal_unref( mTbmSurface );
-      mTbmSurface = NULL;
-    }
-  }
+  DestroySurface();
 
+  mOwnTbmSurface = false;
   mTbmSurface = GetSurfaceFromAny( source );
 
   if( mTbmSurface != NULL )
@@ -355,7 +360,7 @@ bool NativeImageSourceTizen::IsColorDepthSupported( Dali::NativeImageSource::Col
   {
     case Dali::NativeImageSource::COLOR_DEPTH_DEFAULT:
     {
-      format = TBM_FORMAT_RGBA8888;
+      format = TBM_FORMAT_ARGB8888;
       break;
     }
     case Dali::NativeImageSource::COLOR_DEPTH_8:
@@ -375,7 +380,7 @@ bool NativeImageSourceTizen::IsColorDepthSupported( Dali::NativeImageSource::Col
     }
     case Dali::NativeImageSource::COLOR_DEPTH_32:
     {
-      format = TBM_FORMAT_RGBA8888;
+      format = TBM_FORMAT_ARGB8888;
       break;
     }
   }
@@ -396,32 +401,41 @@ bool NativeImageSourceTizen::IsColorDepthSupported( Dali::NativeImageSource::Col
   return false;
 }
 
-bool NativeImageSourceTizen::GlExtensionCreate()
+bool NativeImageSourceTizen::CreateResource()
 {
   // 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 )
+  if( !eglBuffer || !tbm_surface_internal_is_valid( mTbmSurface ) )
   {
     return false;
   }
 
+  mEglImageExtensions = mEglGraphics->GetImageExtensions();
+  DALI_ASSERT_DEBUG( mEglImageExtensions );
+
   mEglImageKHR = mEglImageExtensions->CreateImageKHR( eglBuffer );
 
   return mEglImageKHR != NULL;
 }
 
-void NativeImageSourceTizen::GlExtensionDestroy()
+void NativeImageSourceTizen::DestroyResource()
 {
+  Dali::Mutex::ScopedLock lock( mMutex );
   if( mEglImageKHR )
   {
     mEglImageExtensions->DestroyImageKHR(mEglImageKHR);
 
     mEglImageKHR = NULL;
   }
+
+  if(mResourceDestructionCallback)
+  {
+    mResourceDestructionCallback->Trigger();
+  }
 }
 
-unsigned int NativeImageSourceTizen::TargetTexture()
+uint32_t NativeImageSourceTizen::TargetTexture()
 {
   mEglImageExtensions->TargetTextureKHR(mEglImageKHR);
 
@@ -430,11 +444,12 @@ unsigned int NativeImageSourceTizen::TargetTexture()
 
 void NativeImageSourceTizen::PrepareTexture()
 {
+  Dali::Mutex::ScopedLock lock( mMutex );
   if( mSetSource )
   {
     void* eglImage = mEglImageKHR;
 
-    if( GlExtensionCreate() )
+    if( CreateResource() )
     {
       TargetTexture();
     }
@@ -445,54 +460,31 @@ void NativeImageSourceTizen::PrepareTexture()
   }
 }
 
-int NativeImageSourceTizen::GetPixelDepth(Dali::NativeImageSource::ColorDepth depth) const
-{
-  switch (depth)
-  {
-    case Dali::NativeImageSource::COLOR_DEPTH_DEFAULT:
-    {
-      // ToDo: Get the default screen depth
-      return 32;
-    }
-    case Dali::NativeImageSource::COLOR_DEPTH_8:
-    {
-      return 8;
-    }
-    case Dali::NativeImageSource::COLOR_DEPTH_16:
-    {
-      return 16;
-    }
-    case Dali::NativeImageSource::COLOR_DEPTH_24:
-    {
-      return 24;
-    }
-    case Dali::NativeImageSource::COLOR_DEPTH_32:
-    {
-      return 32;
-    }
-    default:
-    {
-      DALI_ASSERT_DEBUG(0 && "unknown color enum");
-      return 0;
-    }
-  }
-}
-
-const char* NativeImageSourceTizen::GetCustomFragmentPreFix()
+const char* NativeImageSourceTizen::GetCustomFragmentPrefix() const
 {
   return FRAGMENT_PREFIX;
 }
 
-const char* NativeImageSourceTizen::GetCustomSamplerTypename()
+const char* NativeImageSourceTizen::GetCustomSamplerTypename() const
 {
   return SAMPLER_TYPE;
 }
 
-int NativeImageSourceTizen::GetEglImageTextureTarget()
+int NativeImageSourceTizen::GetTextureTarget() const
 {
   return GL_TEXTURE_EXTERNAL_OES;
 }
 
+Any NativeImageSourceTizen::GetNativeImageHandle() const
+{
+  return GetNativeImageSource();
+}
+
+bool NativeImageSourceTizen::SourceChanged() const
+{
+  return false;
+}
+
 bool NativeImageSourceTizen::CheckBlending( tbm_format format )
 {
   if( mTbmFormat != format )
@@ -511,6 +503,57 @@ 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, &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