X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fimaging%2Ftizen%2Fnative-image-source-impl-tizen.cpp;h=bbc14a7aa43bd9f1127f6ea997b9524f9cc285b8;hb=adeaef29df5f659913abf12fd331af8a4464f0f7;hp=e4bcc00fc6aef789a75ef40879d2f6e431c97198;hpb=1ed9b0b5036583fcd39f387783ac1a6281715c6f;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/imaging/tizen/native-image-source-impl-tizen.cpp b/dali/internal/imaging/tizen/native-image-source-impl-tizen.cpp index e4bcc00..bbc14a7 100644 --- a/dali/internal/imaging/tizen/native-image-source-impl-tizen.cpp +++ b/dali/internal/imaging/tizen/native-image-source-impl-tizen.cpp @@ -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. @@ -21,32 +21,27 @@ // EXTERNAL INCLUDES #include #include -#include #include +#include // INTERNAL INCLUDES -#include -#include +#include #include -#include - -// Allow this to be encoded and saved: -#include +#include +#include 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 +53,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(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." ); + NativeImageSourceTizen* image = new NativeImageSourceTizen(width, height, depth, nativeImageSource); + DALI_ASSERT_DEBUG(image && "NativeImageSource allocation failed."); - if( image ) + if(image) { image->Initialize(); } @@ -78,80 +74,82 @@ NativeImageSourceTizen* NativeImageSourceTizen::New(unsigned int width, unsigned return image; } -NativeImageSourceTizen::NativeImageSourceTizen( unsigned int width, unsigned int 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 ) +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) { - DALI_ASSERT_ALWAYS( Adaptor::IsAvailable() ); + DALI_ASSERT_ALWAYS(Adaptor::IsAvailable()); - GraphicsInterface* graphics = &( Adaptor::GetImplementation( Adaptor::Get() ).GetGraphicsInterface() ); - mEglGraphics = static_cast(graphics); + GraphicsInterface* graphics = &(Adaptor::GetImplementation(Adaptor::Get()).GetGraphicsInterface()); + mEglGraphics = static_cast(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; } } @@ -161,22 +159,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(source); } else { @@ -184,179 +182,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& pixbuf, unsigned& width, unsigned& height, Pixel::Format& pixelFormat) const { - 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 ) -{ - 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: @@ -376,48 +378,58 @@ 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 ) + EGLClientBuffer eglBuffer = reinterpret_cast(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 ); + // if resource of egl was not destroyed, destroy it first + DestroyResource(); + + mEglImageKHR = mEglImageExtensions->CreateImageKHR(eglBuffer); return mEglImageKHR != NULL; } -void NativeImageSourceTizen::GlExtensionDestroy() +void NativeImageSourceTizen::DestroyResource() { - if( mEglImageKHR ) + Dali::Mutex::ScopedLock lock(mMutex); + if(mEglImageKHR) { mEglImageExtensions->DestroyImageKHR(mEglImageKHR); @@ -425,7 +437,7 @@ void NativeImageSourceTizen::GlExtensionDestroy() } } -unsigned int NativeImageSourceTizen::TargetTexture() +uint32_t NativeImageSourceTizen::TargetTexture() { mEglImageExtensions->TargetTextureKHR(mEglImageKHR); @@ -434,43 +446,55 @@ unsigned int NativeImageSourceTizen::TargetTexture() void NativeImageSourceTizen::PrepareTexture() { - 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() +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; } -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; @@ -482,8 +506,53 @@ 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; +} + } // namespace Adaptor -} // namespace internal +} // namespace Internal } // namespace Dali