/*
- * 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/integration-api/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
{
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." );
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 ),
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 );
{
case Dali::NativeImageSource::COLOR_DEPTH_DEFAULT:
{
- format = TBM_FORMAT_RGBA8888;
+ format = TBM_FORMAT_ARGB8888;
depth = 32;
break;
}
}
case Dali::NativeImageSource::COLOR_DEPTH_32:
{
- format = TBM_FORMAT_RGBA8888;
+ format = TBM_FORMAT_ARGB8888;
depth = 32;
break;
}
}
}
-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 );
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;
}
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" );
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 )
{
case Dali::NativeImageSource::COLOR_DEPTH_DEFAULT:
{
- format = TBM_FORMAT_RGBA8888;
+ format = TBM_FORMAT_ARGB8888;
break;
}
case Dali::NativeImageSource::COLOR_DEPTH_8:
}
case Dali::NativeImageSource::COLOR_DEPTH_32:
{
- format = TBM_FORMAT_RGBA8888;
+ format = TBM_FORMAT_ARGB8888;
break;
}
}
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);
void NativeImageSourceTizen::PrepareTexture()
{
+ Dali::Mutex::ScopedLock lock( mMutex );
if( mSetSource )
{
void* eglImage = mEglImageKHR;
- if( GlExtensionCreate() )
+ if( CreateResource() )
{
TargetTexture();
}
}
}
-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 )
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