/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
#include <Ecore_Wayland.h>
#include <tbm_bufmgr.h>
#include <tbm_surface_queue.h>
+#include <tbm_surface_internal.h>
// INTERNAL INCLUDES
#include <trigger-event.h>
mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ),
mTbmFormat( isTransparent ? TBM_FORMAT_ARGB8888 : TBM_FORMAT_RGB888 ),
mOwnSurface( false ),
+ mDrawableCompleted( false ),
+ mTbmQueue( NULL ),
mConsumeSurface( NULL ),
mThreadSynchronization( NULL )
{
ColorDepth mColorDepth;
tbm_format mTbmFormat;
bool mOwnSurface;
+ bool mDrawableCompleted;
tbm_surface_queue_h mTbmQueue;
tbm_surface_h mConsumeSurface;
{
ecore_wl_init(NULL);
CreateNativeRenderable();
+ setenv( "EGL_PLATFORM", "tbm", 1 );
}
NativeRenderSurface::~NativeRenderSurface()
// release the surface if we own one
if( mImpl->mOwnSurface )
{
-
- if( mImpl->mConsumeSurface )
- {
- tbm_surface_queue_release( mImpl->mTbmQueue, mImpl->mConsumeSurface );
- mImpl->mConsumeSurface = NULL;
- }
+ ReleaseDrawable();
if( mImpl->mTbmQueue )
{
DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::General, "Own tbm surface queue destroy\n" );
}
+
+ ecore_wl_shutdown();
}
void NativeRenderSurface::SetRenderNotification( TriggerEventInterface* renderNotification )
tbm_surface_h NativeRenderSurface::GetDrawable()
{
- ConditionalWait::ScopedLock lock( mImpl->mTbmSurfaceCondition );
-
return mImpl->mConsumeSurface;
}
void NativeRenderSurface::InitializeEgl( EglInterface& egl )
{
DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
+ unsetenv( "EGL_PLATFORM" );
Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
- eglImpl.CreateSurfaceWindow( (EGLNativeWindowType)mImpl->mTbmQueue, mImpl->mColorDepth );
+ eglImpl.CreateSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mImpl->mTbmQueue ), mImpl->mColorDepth );
}
void NativeRenderSurface::DestroyEglSurface( EglInterface& egl )
{
DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
- if( mImpl->mConsumeSurface )
- {
- tbm_surface_queue_release( mImpl->mTbmQueue, mImpl->mConsumeSurface );
- mImpl->mConsumeSurface = NULL;
- }
-
- if( mImpl->mTbmQueue )
- {
- tbm_surface_queue_destroy( mImpl->mTbmQueue );
- }
-
- CreateNativeRenderable();
-
if( !mImpl->mTbmQueue )
{
return false;
Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
- return eglImpl.ReplaceSurfaceWindow( (EGLNativeWindowType)mImpl->mTbmQueue ); // reinterpret_cast does not compile
+ return eglImpl.ReplaceSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mImpl->mTbmQueue ) );
}
void NativeRenderSurface::StartRender()
{
}
-bool NativeRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
+bool NativeRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction&, bool )
{
// nothing to do for pixmaps
return true;
}
-void NativeRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface )
+void NativeRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface )
{
Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
eglImpl.SwapBuffers();
- // flush gl instruction queue
- glAbstraction.Flush();
+ if( mImpl->mThreadSynchronization )
+ {
+ mImpl->mThreadSynchronization->PostRenderStarted();
+ }
+ if( tbm_surface_queue_can_acquire( mImpl->mTbmQueue, 1 ) )
{
- if( tbm_surface_queue_can_acquire( mImpl->mTbmQueue, 1 ) )
+ if( tbm_surface_queue_acquire( mImpl->mTbmQueue, &mImpl->mConsumeSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
{
- if( tbm_surface_queue_acquire( mImpl->mTbmQueue, &mImpl->mConsumeSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
- {
- DALI_LOG_ERROR( "Failed aquire consume tbm_surface\n" );
- return;
- }
+ DALI_LOG_ERROR( "Failed to aquire a tbm_surface\n" );
+ return;
}
}
+ tbm_surface_internal_ref( mImpl->mConsumeSurface );
+
+ if( replacingSurface )
+ {
+ ConditionalWait::ScopedLock lock( mImpl->mTbmSurfaceCondition );
+ mImpl->mDrawableCompleted = true;
+ mImpl->mTbmSurfaceCondition.Notify( lock );
+ }
+
// create damage for client applications which wish to know the update timing
- if( mImpl->mRenderNotification )
+ if( !replacingSurface && mImpl->mRenderNotification )
{
// use notification trigger
- // Tell the event-thread to render the pixmap
+ // Tell the event-thread to render the tbm_surface
mImpl->mRenderNotification->Trigger();
}
- else
+
+ if( mImpl->mThreadSynchronization )
{
- // FIXME
+ // wait until the event-thread completed to use the tbm_surface
+ mImpl->mThreadSynchronization->PostRenderWaitForCompletion();
}
+ // release the consumed surface after post render was completed
+ ReleaseDrawable();
}
void NativeRenderSurface::StopRender()
void NativeRenderSurface::CreateNativeRenderable()
{
// check we're creating one with a valid size
- DALI_ASSERT_ALWAYS( mImpl->mPosition.width > 0 && mImpl->mPosition.height > 0 && "Pixmap size is invalid" );
+ DALI_ASSERT_ALWAYS( mImpl->mPosition.width > 0 && mImpl->mPosition.height > 0 && "tbm_surface size is invalid" );
mImpl->mTbmQueue = tbm_surface_queue_create( 3, mImpl->mPosition.width, mImpl->mPosition.height, mImpl->mTbmFormat, TBM_BO_DEFAULT );
}
}
-void NativeRenderSurface::ReleaseSurface()
+void NativeRenderSurface::ReleaseLock()
{
- if( mImpl->mConsumeSurface )
+ if( mImpl->mThreadSynchronization )
{
- tbm_surface_queue_release( mImpl->mTbmQueue, mImpl->mConsumeSurface );
- mImpl->mConsumeSurface = NULL;
+ mImpl->mThreadSynchronization->PostRenderComplete();
}
}
-void NativeRenderSurface::ReleaseLock()
+void NativeRenderSurface::WaitUntilSurfaceReplaced()
{
- if( mImpl->mThreadSynchronization )
+ ConditionalWait::ScopedLock lock( mImpl->mTbmSurfaceCondition );
+ while( !mImpl->mDrawableCompleted )
{
- mImpl->mThreadSynchronization->PostRenderComplete();
+ mImpl->mTbmSurfaceCondition.Wait( lock );
+ }
+
+ mImpl->mDrawableCompleted = false;
+}
+
+void NativeRenderSurface::ReleaseDrawable()
+{
+ if( mImpl->mConsumeSurface )
+ {
+ tbm_surface_internal_unref( mImpl->mConsumeSurface );
+
+ if( tbm_surface_internal_is_valid( mImpl->mConsumeSurface ) )
+ {
+ tbm_surface_queue_release( mImpl->mTbmQueue, mImpl->mConsumeSurface );
+ }
+ mImpl->mConsumeSurface = NULL;
}
}