{
#define TBM_SURFACE_QUEUE_SIZE 3
-const char* SAMPLER_TYPE = "samplerExternalOES";
+const char* SAMPLER_TYPE = "samplerExternalOES";
// clang-format off
int FORMATS_BLENDING_REQUIRED[] = {
} // namespace
-NativeImageSourceQueueTizen* NativeImageSourceQueueTizen::New(uint32_t width, uint32_t height, Dali::NativeImageSourceQueue::ColorDepth depth, Any nativeImageSourceQueue)
+NativeImageSourceQueueTizen* NativeImageSourceQueueTizen::New(uint32_t width, uint32_t height, Dali::NativeImageSourceQueue::ColorFormat colorFormat, Any nativeImageSourceQueue)
{
- NativeImageSourceQueueTizen* image = new NativeImageSourceQueueTizen(width, height, depth, nativeImageSourceQueue);
+ NativeImageSourceQueueTizen* image = new NativeImageSourceQueueTizen(width, height, colorFormat, nativeImageSourceQueue);
DALI_ASSERT_DEBUG(image && "NativeImageSourceQueueTizen allocation failed.");
if(image)
{
- image->Initialize(depth);
+ image->Initialize(colorFormat);
}
return image;
}
-NativeImageSourceQueueTizen::NativeImageSourceQueueTizen(uint32_t width, uint32_t height, Dali::NativeImageSourceQueue::ColorDepth depth, Any nativeImageSourceQueue)
-: mCustomFragmentPrefix(),
- mMutex(),
+NativeImageSourceQueueTizen::NativeImageSourceQueueTizen(uint32_t width, uint32_t height, Dali::NativeImageSourceQueue::ColorFormat colorFormat, Any nativeImageSourceQueue)
+: mMutex(),
mWidth(width),
mHeight(height),
mTbmQueue(NULL),
mConsumeSurface(NULL),
mEglImages(),
+ mBuffers(),
mEglGraphics(NULL),
mEglImageExtensions(NULL),
mOwnTbmQueue(false),
- mBlendingRequired(false)
+ mBlendingRequired(false),
+ mIsResized(false)
{
DALI_ASSERT_ALWAYS(Adaptor::IsAvailable());
GraphicsInterface* graphics = &(Adaptor::GetImplementation(Adaptor::Get()).GetGraphicsInterface());
mEglGraphics = static_cast<EglGraphics*>(graphics);
- mCustomFragmentPrefix = mEglGraphics->GetEglImageExtensionString();
-
mTbmQueue = GetSurfaceFromAny(nativeImageSourceQueue);
if(mTbmQueue != NULL)
}
}
-void NativeImageSourceQueueTizen::Initialize(Dali::NativeImageSourceQueue::ColorDepth depth)
+void NativeImageSourceQueueTizen::Initialize(Dali::NativeImageSourceQueue::ColorFormat colorFormat)
{
if(mWidth == 0 || mHeight == 0)
{
if(mTbmQueue == NULL)
{
- int format = TBM_FORMAT_ARGB8888;
+ int tbmFormat = TBM_FORMAT_ARGB8888;
- switch(depth)
+ switch(colorFormat)
{
- case Dali::NativeImageSourceQueue::COLOR_DEPTH_DEFAULT:
- case Dali::NativeImageSourceQueue::COLOR_DEPTH_32:
+ case Dali::NativeImageSourceQueue::ColorFormat::RGBA8888:
{
- format = TBM_FORMAT_ARGB8888;
+ tbmFormat = TBM_FORMAT_ARGB8888;
mBlendingRequired = true;
break;
}
- case Dali::NativeImageSourceQueue::COLOR_DEPTH_24:
+ case Dali::NativeImageSourceQueue::ColorFormat::RGBX8888:
{
- format = TBM_FORMAT_RGB888;
+ tbmFormat = TBM_FORMAT_XRGB8888;
+ mBlendingRequired = false;
+ break;
+ }
+ case Dali::NativeImageSourceQueue::ColorFormat::RGB888:
+ {
+ tbmFormat = TBM_FORMAT_RGB888;
mBlendingRequired = false;
break;
}
default:
{
- DALI_LOG_WARNING("Wrong color depth.\n");
+ DALI_LOG_WARNING("Wrong color format.\n");
return;
}
}
- mTbmQueue = tbm_surface_queue_create(TBM_SURFACE_QUEUE_SIZE, mWidth, mHeight, format, 0);
+ mTbmQueue = tbm_surface_queue_create(TBM_SURFACE_QUEUE_SIZE, mWidth, mHeight, tbmFormat, 0);
if(!mTbmQueue)
{
DALI_LOG_ERROR("NativeImageSourceQueueTizen::Initialize: tbm_surface_queue_create is failed! [%p]\n", mTbmQueue);
{
Dali::Mutex::ScopedLock lock(mMutex);
- tbm_surface_queue_reset(mTbmQueue, width, height, tbm_surface_queue_get_format(mTbmQueue));
+ if(mWidth == width && mHeight == height)
+ {
+ return;
+ }
- mWidth = width;
- mHeight = height;
+ tbm_surface_queue_reset(mTbmQueue, width, height, tbm_surface_queue_get_format(mTbmQueue));
- ResetEglImageList();
+ mWidth = width;
+ mHeight = height;
+ mIsResized = true;
}
void NativeImageSourceQueueTizen::IgnoreSourceImage()
}
}
+bool NativeImageSourceQueueTizen::CanDequeueBuffer()
+{
+ Dali::Mutex::ScopedLock lock(mMutex);
+ if(tbm_surface_queue_can_dequeue(mTbmQueue, 0))
+ {
+ return true;
+ }
+ return false;
+}
+
+uint8_t* NativeImageSourceQueueTizen::DequeueBuffer(uint32_t& width, uint32_t& height, uint32_t& stride)
+{
+ Dali::Mutex::ScopedLock lock(mMutex);
+ if(mTbmQueue == NULL)
+ {
+ DALI_LOG_ERROR("TbmQueue is NULL");
+ return NULL;
+ }
+
+ 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;
+ }
+
+ 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;
+}
+
bool NativeImageSourceQueueTizen::CreateResource()
{
mEglImageExtensions = mEglGraphics->GetImageExtensions();
{
Dali::Mutex::ScopedLock lock(mMutex);
- ResetEglImageList();
+ ResetEglImageList(true);
}
uint32_t NativeImageSourceQueueTizen::TargetTexture()
}
}
+ if(mIsResized)
+ {
+ ResetEglImageList(false);
+ mIsResized = false;
+ }
+
if(mConsumeSurface)
{
bool existing = false;
}
}
-const char* NativeImageSourceQueueTizen::GetCustomFragmentPrefix() const
+bool NativeImageSourceQueueTizen::ApplyNativeFragmentShader(std::string& shader)
{
- return mCustomFragmentPrefix;
+ return mEglGraphics->ApplyNativeFragmentShader(shader, SAMPLER_TYPE);
}
const char* NativeImageSourceQueueTizen::GetCustomSamplerTypename() const
return false;
}
-void NativeImageSourceQueueTizen::ResetEglImageList()
+void NativeImageSourceQueueTizen::ResetEglImageList(bool releaseConsumeSurface)
{
- if(mConsumeSurface)
+ // 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))
{