X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fimaging%2Ftizen%2Fnative-image-source-queue-impl-tizen.cpp;h=b5d926b2ec99bb6b2e26598f91364368c6ce41c5;hb=ab2990078aa8f0d16ebb40100b4e785f60444790;hp=157d3b8eb592c973cf4e82489af72293c02bfbc4;hpb=ba06dd22595200b399e43416e6b8141ed2ea5792;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/imaging/tizen/native-image-source-queue-impl-tizen.cpp b/dali/internal/imaging/tizen/native-image-source-queue-impl-tizen.cpp index 157d3b8..b5d926b 100644 --- a/dali/internal/imaging/tizen/native-image-source-queue-impl-tizen.cpp +++ b/dali/internal/imaging/tizen/native-image-source-queue-impl-tizen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -24,26 +24,20 @@ #include // INTERNAL INCLUDES -#include -#include +#include #include +#include +#include namespace Dali { - namespace Internal { - namespace Adaptor { - namespace { -#define TBM_SURFACE_QUEUE_SIZE 3 - -const char* FRAGMENT_PREFIX = "#extension GL_OES_EGL_image_external:require\n"; -const char* SAMPLER_TYPE = "samplerExternalOES"; - +// clang-format off int FORMATS_BLENDING_REQUIRED[] = { TBM_FORMAT_ARGB4444, TBM_FORMAT_ABGR4444, TBM_FORMAT_RGBA4444, TBM_FORMAT_BGRA4444, @@ -55,103 +49,140 @@ int 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; +const char* SAMPLER_TYPE = "samplerExternalOES"; + +constexpr int32_t NUM_FORMATS_BLENDING_REQUIRED = 18; +constexpr int32_t DEFAULT_TBM_SURFACE_QUEUE_SIZE = 3u; +constexpr auto TBM_SURFACE_QUEUE_SIZE = "DALI_TBM_SURFACE_QUEUE_SIZE"; + +int32_t GetTbmSurfaceQueueSize() +{ + static auto queueSizeString = EnvironmentVariable::GetEnvironmentVariable(TBM_SURFACE_QUEUE_SIZE); + static int32_t queueSize = queueSizeString ? std::atoi(queueSizeString) : DEFAULT_TBM_SURFACE_QUEUE_SIZE; + return queueSize; } -NativeImageSourceQueueTizen* NativeImageSourceQueueTizen::New( unsigned int width, unsigned int height, Dali::NativeImageSourceQueue::ColorDepth depth, Any nativeImageSourceQueue ) +} // namespace + +NativeImageSourceQueueTizen* NativeImageSourceQueueTizen::New(uint32_t width, uint32_t height, Dali::NativeImageSourceQueue::ColorFormat colorFormat, Any nativeImageSourceQueue) { - NativeImageSourceQueueTizen* image = new NativeImageSourceQueueTizen( width, height, depth, nativeImageSourceQueue ); - DALI_ASSERT_DEBUG( image && "NativeImageSourceQueueTizen allocation failed." ); + NativeImageSourceQueueTizen* image = new NativeImageSourceQueueTizen(width, height, colorFormat, nativeImageSourceQueue); + DALI_ASSERT_DEBUG(image && "NativeImageSourceQueueTizen allocation failed."); - if( image ) + if(image) { - image->Initialize( depth ); + image->Initialize(colorFormat); } return image; } -NativeImageSourceQueueTizen::NativeImageSourceQueueTizen( unsigned int width, unsigned int height, Dali::NativeImageSourceQueue::ColorDepth depth, Any nativeImageSourceQueue ) -: mWidth( width ), - mHeight( height ), - mTbmQueue( NULL ), - mConsumeSurface( NULL ), +NativeImageSourceQueueTizen::NativeImageSourceQueueTizen(uint32_t width, uint32_t height, Dali::NativeImageSourceQueue::ColorFormat colorFormat, Any nativeImageSourceQueue) +: mMutex(), + mWidth(width), + mHeight(height), + mTbmQueue(NULL), + mConsumeSurface(NULL), mEglImages(), - mEglImageExtensions( NULL ), - mOwnTbmQueue( false ), - mBlendingRequired( false ) + mBuffers(), + mEglGraphics(NULL), + mEglImageExtensions(NULL), + mOwnTbmQueue(false), + mBlendingRequired(false), + mIsResized(false), + mFreeRequest(false) { - DALI_ASSERT_ALWAYS( Adaptor::IsAvailable() ); - EglFactory& eglFactory = Adaptor::GetImplementation( Adaptor::Get() ).GetEGLFactory(); - mEglImageExtensions = eglFactory.GetImageExtensions(); - DALI_ASSERT_DEBUG( mEglImageExtensions ); + DALI_ASSERT_ALWAYS(Adaptor::IsAvailable()); + + GraphicsInterface* graphics = &(Adaptor::GetImplementation(Adaptor::Get()).GetGraphicsInterface()); + mEglGraphics = static_cast(graphics); - mTbmQueue = GetSurfaceFromAny( nativeImageSourceQueue ); + mTbmQueue = GetSurfaceFromAny(nativeImageSourceQueue); - if( mTbmQueue != NULL ) + if(mTbmQueue != NULL) { - mBlendingRequired = CheckBlending( tbm_surface_queue_get_format( mTbmQueue ) ); - mWidth = tbm_surface_queue_get_width( mTbmQueue ); - mHeight = tbm_surface_queue_get_height( mTbmQueue ); + mBlendingRequired = CheckBlending(tbm_surface_queue_get_format(mTbmQueue)); + mWidth = tbm_surface_queue_get_width(mTbmQueue); + mHeight = tbm_surface_queue_get_height(mTbmQueue); } } NativeImageSourceQueueTizen::~NativeImageSourceQueueTizen() { - if( mOwnTbmQueue ) + if(mOwnTbmQueue) { - DestroyQueue(); + if(mTbmQueue != NULL) + { + tbm_surface_queue_destroy(mTbmQueue); + } } } -void NativeImageSourceQueueTizen::Initialize( Dali::NativeImageSourceQueue::ColorDepth depth ) +void NativeImageSourceQueueTizen::Initialize(Dali::NativeImageSourceQueue::ColorFormat colorFormat) { - if( mTbmQueue != NULL || mWidth == 0 || mHeight == 0 ) + if(mWidth == 0 || mHeight == 0) { return; } - int format = TBM_FORMAT_ARGB8888; - - switch( depth ) + if(mTbmQueue == NULL) { - case Dali::NativeImageSourceQueue::COLOR_DEPTH_DEFAULT: - case Dali::NativeImageSourceQueue::COLOR_DEPTH_32: - { - format = TBM_FORMAT_ARGB8888; - mBlendingRequired = true; - break; - } - case Dali::NativeImageSourceQueue::COLOR_DEPTH_24: + int tbmFormat = TBM_FORMAT_ARGB8888; + + switch(colorFormat) { - format = TBM_FORMAT_RGB888; - mBlendingRequired = false; - break; + case Dali::NativeImageSourceQueue::ColorFormat::RGBA8888: // TODO : Implement me after other codes fixed. + case Dali::NativeImageSourceQueue::ColorFormat::BGRA8888: + { + tbmFormat = TBM_FORMAT_ARGB8888; + mBlendingRequired = true; + break; + } + case Dali::NativeImageSourceQueue::ColorFormat::RGBX8888: // TODO : Implement me after other codes fixed. + case Dali::NativeImageSourceQueue::ColorFormat::BGRX8888: + { + tbmFormat = TBM_FORMAT_XRGB8888; + mBlendingRequired = false; + break; + } + case Dali::NativeImageSourceQueue::ColorFormat::RGB888: // TODO : Implement me after other codes fixed. + case Dali::NativeImageSourceQueue::ColorFormat::BGR888: + { + tbmFormat = TBM_FORMAT_RGB888; + mBlendingRequired = false; + break; + } + default: + { + DALI_LOG_WARNING("Wrong color format.\n"); + return; + } } - default: + + mTbmQueue = tbm_surface_queue_create(GetTbmSurfaceQueueSize(), mWidth, mHeight, tbmFormat, 0); + if(!mTbmQueue) { - DALI_LOG_WARNING( "Wrong color depth.\n" ); + DALI_LOG_ERROR("NativeImageSourceQueueTizen::Initialize: tbm_surface_queue_create is failed! [%p]\n", mTbmQueue); return; } - } - - mTbmQueue = tbm_surface_queue_create( TBM_SURFACE_QUEUE_SIZE, mWidth, mHeight, format, 0 ); - mOwnTbmQueue = true; + mOwnTbmQueue = true; + } } -tbm_surface_queue_h NativeImageSourceQueueTizen::GetSurfaceFromAny( Any source ) const +tbm_surface_queue_h NativeImageSourceQueueTizen::GetSurfaceFromAny(Any source) const { - if( source.Empty() ) + if(source.Empty()) { return NULL; } - if( source.GetType() == typeid( tbm_surface_queue_h ) ) + if(source.GetType() == typeid(tbm_surface_queue_h)) { - return AnyCast< tbm_surface_queue_h >( source ); + return AnyCast(source); } else { @@ -161,138 +192,277 @@ tbm_surface_queue_h NativeImageSourceQueueTizen::GetSurfaceFromAny( Any source ) Any NativeImageSourceQueueTizen::GetNativeImageSourceQueue() const { - return Any( mTbmQueue ); + return Any(mTbmQueue); } -void NativeImageSourceQueueTizen::SetSource( Any source ) +void NativeImageSourceQueueTizen::SetSize(uint32_t width, uint32_t height) { - if( mOwnTbmQueue ) + Dali::Mutex::ScopedLock lock(mMutex); + + if(mWidth == width && mHeight == height) { - DestroyQueue(); + return; } - mTbmQueue = GetSurfaceFromAny( source ); + tbm_surface_queue_reset(mTbmQueue, width, height, tbm_surface_queue_get_format(mTbmQueue)); + + mWidth = width; + mHeight = height; + mIsResized = true; +} - if( mTbmQueue != NULL ) +void NativeImageSourceQueueTizen::IgnoreSourceImage() +{ + Dali::Mutex::ScopedLock lock(mMutex); + tbm_surface_h surface; + + if(tbm_surface_queue_can_acquire(mTbmQueue, 0)) { - mBlendingRequired = CheckBlending( tbm_surface_queue_get_format( mTbmQueue ) ); - mWidth = tbm_surface_queue_get_width( mTbmQueue ); - mHeight = tbm_surface_queue_get_height( mTbmQueue ); + if(tbm_surface_queue_acquire(mTbmQueue, &surface) != TBM_SURFACE_QUEUE_ERROR_NONE) + { + DALI_LOG_ERROR("NativeImageSourceQueueTizen::IgnoreSourceImage: Failed to aquire a tbm_surface\n"); + return; + } + + if(tbm_surface_internal_is_valid(surface)) + { + tbm_surface_queue_release(mTbmQueue, surface); + } } } -bool NativeImageSourceQueueTizen::GlExtensionCreate() +bool NativeImageSourceQueueTizen::CanDequeueBuffer() { - return true; + Dali::Mutex::ScopedLock lock(mMutex); + if(tbm_surface_queue_can_dequeue(mTbmQueue, 0)) + { + return true; + } + return false; } -void NativeImageSourceQueueTizen::GlExtensionDestroy() +uint8_t* NativeImageSourceQueueTizen::DequeueBuffer(uint32_t& width, uint32_t& height, uint32_t& stride) { - for( auto&& iter : mEglImages ) + Dali::Mutex::ScopedLock lock(mMutex); + if(mTbmQueue == NULL) { - mEglImageExtensions->DestroyImageKHR( iter.second ); + DALI_LOG_ERROR("TbmQueue is NULL"); + return NULL; + } - tbm_surface_internal_unref( iter.first ); + tbm_surface_h tbmSurface; + if(tbm_surface_queue_dequeue(mTbmQueue, &tbmSurface) != TBM_SURFACE_QUEUE_ERROR_NONE) + { + DALI_LOG_ERROR("Failed to dequeue a tbm_surface [%p]\n", tbmSurface); + return NULL; } - mEglImages.clear(); + + tbm_surface_info_s info; + int ret = tbm_surface_map(tbmSurface, TBM_OPTION_WRITE, &info); + if(ret != TBM_SURFACE_ERROR_NONE) + { + DALI_LOG_ERROR("tbm_surface_map is failed! [%d] [%p]\n", ret, tbmSurface); + tbm_surface_queue_cancel_dequeue(mTbmQueue, tbmSurface); + return NULL; + } + + unsigned char* buffer = info.planes[0].ptr; + if(!buffer) + { + DALI_LOG_ERROR("tbm buffer pointer is null! [%p]\n", tbmSurface); + tbm_surface_unmap(tbmSurface); + tbm_surface_queue_cancel_dequeue(mTbmQueue, tbmSurface); + return NULL; + } + + tbm_surface_internal_ref(tbmSurface); + + stride = info.planes[0].stride; + width = mWidth; + height = mHeight; + + // Push the buffer + mBuffers.push_back(BufferPair(tbmSurface, buffer)); + return buffer; +} + +bool NativeImageSourceQueueTizen::EnqueueBuffer(uint8_t* buffer) +{ + Dali::Mutex::ScopedLock lock(mMutex); + auto bufferInstance = std::find_if(mBuffers.begin(), + mBuffers.end(), + [buffer](BufferPair pair) { return (pair.second == buffer); }); + if(bufferInstance != mBuffers.end()) + { + tbm_surface_internal_unref((*bufferInstance).first); + tbm_surface_unmap((*bufferInstance).first); + tbm_surface_queue_enqueue(mTbmQueue, (*bufferInstance).first); + mBuffers.erase(bufferInstance); + return true; + } + return false; } -unsigned int NativeImageSourceQueueTizen::TargetTexture() +void NativeImageSourceQueueTizen::FreeReleasedBuffers() +{ + Dali::Mutex::ScopedLock lock(mMutex); + mFreeRequest = true; +} + +bool NativeImageSourceQueueTizen::CreateResource() +{ + mEglImageExtensions = mEglGraphics->GetImageExtensions(); + DALI_ASSERT_DEBUG(mEglImageExtensions); + + return true; +} + +void NativeImageSourceQueueTizen::DestroyResource() +{ + Dali::Mutex::ScopedLock lock(mMutex); + + ResetEglImageList(true); +} + +uint32_t NativeImageSourceQueueTizen::TargetTexture() { return 0; } void NativeImageSourceQueueTizen::PrepareTexture() { - tbm_surface_h oldSurface = mConsumeSurface; + Dali::Mutex::ScopedLock lock(mMutex); - bool needToWait = ( mConsumeSurface == NULL ) ? true : false; + bool updated = false; - if( tbm_surface_queue_can_acquire( mTbmQueue, needToWait ) ) + do { - if( tbm_surface_queue_acquire( mTbmQueue, &mConsumeSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE ) + tbm_surface_h oldSurface = mConsumeSurface; + + if(tbm_surface_queue_can_acquire(mTbmQueue, 0)) { - DALI_LOG_ERROR( "Failed to aquire a tbm_surface\n" ); - return; + if(tbm_surface_queue_acquire(mTbmQueue, &mConsumeSurface) != TBM_SURFACE_QUEUE_ERROR_NONE) + { + DALI_LOG_ERROR("Failed to aquire a tbm_surface\n"); + return; + } + + if(oldSurface) + { + if(tbm_surface_internal_is_valid(oldSurface)) + { + tbm_surface_queue_release(mTbmQueue, oldSurface); + } + } + updated = true; } - } + else + { + break; + } + } while(mFreeRequest); // Get the last one if buffer free was requested - if( oldSurface && oldSurface != mConsumeSurface ) + if(updated) { - if( tbm_surface_internal_is_valid( oldSurface ) ) + if(mIsResized) { - tbm_surface_queue_release( mTbmQueue, oldSurface ); + ResetEglImageList(false); + mIsResized = false; } - } - if( mConsumeSurface ) - { - bool existing = false; - for( auto&& iter : mEglImages ) + if(mConsumeSurface) { - if( iter.first == mConsumeSurface ) + bool existing = false; + for(auto&& iter : mEglImages) { - // Find the surface in the existing list - existing = true; - mEglImageExtensions->TargetTextureKHR( iter.second ); - break; + if(iter.first == mConsumeSurface) + { + // Find the surface in the existing list + existing = true; + mEglImageExtensions->TargetTextureKHR(iter.second); + break; + } } - } - if( !existing ) - { - // Push the surface - tbm_surface_internal_ref( mConsumeSurface ); + if(!existing) + { + // Push the surface + tbm_surface_internal_ref(mConsumeSurface); - void* eglImageKHR = mEglImageExtensions->CreateImageKHR( reinterpret_cast< EGLClientBuffer >( mConsumeSurface ) ); - mEglImageExtensions->TargetTextureKHR( eglImageKHR ); + void* eglImageKHR = mEglImageExtensions->CreateImageKHR(reinterpret_cast(mConsumeSurface)); + mEglImageExtensions->TargetTextureKHR(eglImageKHR); - mEglImages.push_back( EglImagePair( mConsumeSurface, eglImageKHR) ); + mEglImages.push_back(EglImagePair(mConsumeSurface, eglImageKHR)); + } } } + + if(mFreeRequest) + { + auto iter = std::remove_if(mEglImages.begin(), mEglImages.end(), [&](EglImagePair& eglImage) { + if(mConsumeSurface == eglImage.first) return false; + mEglImageExtensions->DestroyImageKHR(eglImage.second); + tbm_surface_internal_unref(eglImage.first); + return true; }); + mEglImages.erase(iter, mEglImages.end()); + + tbm_surface_queue_free_flush(mTbmQueue); + mFreeRequest = false; + } } -const char* NativeImageSourceQueueTizen::GetCustomFragmentPreFix() +bool NativeImageSourceQueueTizen::ApplyNativeFragmentShader(std::string& shader) { - return FRAGMENT_PREFIX; + return mEglGraphics->ApplyNativeFragmentShader(shader, SAMPLER_TYPE); } -const char* NativeImageSourceQueueTizen::GetCustomSamplerTypename() +const char* NativeImageSourceQueueTizen::GetCustomSamplerTypename() const { return SAMPLER_TYPE; } -int NativeImageSourceQueueTizen::GetEglImageTextureTarget() +int NativeImageSourceQueueTizen::GetTextureTarget() const { return GL_TEXTURE_EXTERNAL_OES; } -void NativeImageSourceQueueTizen::DestroyQueue() +Any NativeImageSourceQueueTizen::GetNativeImageHandle() const { - if( mConsumeSurface ) - { - tbm_surface_internal_unref( mConsumeSurface ); + return nullptr; +} + +bool NativeImageSourceQueueTizen::SourceChanged() const +{ + return false; +} - if( tbm_surface_internal_is_valid( mConsumeSurface ) ) +void NativeImageSourceQueueTizen::ResetEglImageList(bool releaseConsumeSurface) +{ + // When Tbm surface queue is reset(resized), the surface acquired before reset() is still valid, not the others. + // We can still use the acquired surface so that we will release it as the oldSurface in PrepareTexture() when the next surface is ready. + if(releaseConsumeSurface && mConsumeSurface) + { + if(tbm_surface_internal_is_valid(mConsumeSurface)) { - tbm_surface_queue_release( mTbmQueue, mConsumeSurface ); + tbm_surface_queue_release(mTbmQueue, mConsumeSurface); } + mConsumeSurface = NULL; } - if( mTbmQueue != NULL ) + for(auto&& iter : mEglImages) { - tbm_surface_queue_destroy( mTbmQueue ); - } + mEglImageExtensions->DestroyImageKHR(iter.second); - mTbmQueue = NULL; - mOwnTbmQueue = false; + tbm_surface_internal_unref(iter.first); + } + mEglImages.clear(); } -bool NativeImageSourceQueueTizen::CheckBlending( int format ) +bool NativeImageSourceQueueTizen::CheckBlending(int format) { - for( int i = 0; i < NUM_FORMATS_BLENDING_REQUIRED; ++i ) + for(int32_t i = 0; i < NUM_FORMATS_BLENDING_REQUIRED; ++i) { - if( format == FORMATS_BLENDING_REQUIRED[i] ) + if(format == FORMATS_BLENDING_REQUIRED[i]) { return true; } @@ -303,6 +473,6 @@ bool NativeImageSourceQueueTizen::CheckBlending( int format ) } // namespace Adaptor -} // namespace internal +} // namespace Internal } // namespace Dali