2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h>
22 #include <dali/integration-api/gl-abstraction.h>
23 #include <dali/integration-api/debug.h>
25 #include <Ecore_Wayland.h>
26 #include <tbm_bufmgr.h>
27 #include <tbm_surface_internal.h>
30 #include <dali/internal/system/common/trigger-event.h>
31 #include <dali/internal/graphics/gles20/egl-implementation.h>
32 #include <dali/internal/window-system/common/display-connection.h>
33 #include <dali/integration-api/thread-synchronization-interface.h>
41 #if defined(DEBUG_ENABLED)
42 Debug::Filter* gNativeSurfaceLogFilter = Debug::Filter::New(Debug::Verbose, false, "LOG_NATIVE_RENDER_SURFACE");
45 } // unnamed namespace
47 NativeRenderSurfaceEcoreWl::NativeRenderSurfaceEcoreWl( Dali::PositionSize positionSize, const std::string& name, bool isTransparent )
48 : mPosition( positionSize ),
50 mRenderNotification( NULL ),
51 mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ),
52 mTbmFormat( isTransparent ? TBM_FORMAT_ARGB8888 : TBM_FORMAT_RGB888 ),
54 mDrawableCompleted( false ),
56 mConsumeSurface( NULL ),
57 mThreadSynchronization( NULL )
59 ecore_wl_init( NULL );
60 CreateNativeRenderable();
61 setenv( "EGL_PLATFORM", "tbm", 1 );
64 NativeRenderSurfaceEcoreWl::~NativeRenderSurfaceEcoreWl()
66 // release the surface if we own one
73 tbm_surface_queue_destroy( mTbmQueue );
76 DALI_LOG_INFO( gNativeSurfaceLogFilter, Debug::General, "Own tbm surface queue destroy\n" );
82 Any NativeRenderSurfaceEcoreWl::GetDrawable()
84 return mConsumeSurface;
87 void NativeRenderSurfaceEcoreWl::SetRenderNotification( TriggerEventInterface* renderNotification )
89 mRenderNotification = renderNotification;
92 void NativeRenderSurfaceEcoreWl::WaitUntilSurfaceReplaced()
94 ConditionalWait::ScopedLock lock( mTbmSurfaceCondition );
95 while( !mDrawableCompleted )
97 mTbmSurfaceCondition.Wait( lock );
100 mDrawableCompleted = false;
103 PositionSize NativeRenderSurfaceEcoreWl::GetPositionSize() const
108 void NativeRenderSurfaceEcoreWl::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical )
113 // 1 inch = 25.4 millimeters
114 xres = ecore_wl_dpi_get();
115 yres = ecore_wl_dpi_get();
117 dpiHorizontal = int( xres + 0.5f ); // rounding
118 dpiVertical = int( yres + 0.5f );
121 void NativeRenderSurfaceEcoreWl::InitializeEgl( EglInterface& egl )
123 DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
124 unsetenv( "EGL_PLATFORM" );
126 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
128 eglImpl.ChooseConfig( true, mColorDepth );
131 void NativeRenderSurfaceEcoreWl::CreateEglSurface( EglInterface& egl )
133 DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
135 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
137 eglImpl.CreateSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mTbmQueue ), mColorDepth );
140 void NativeRenderSurfaceEcoreWl::DestroyEglSurface( EglInterface& egl )
142 DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
144 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
145 eglImpl.DestroySurface();
148 bool NativeRenderSurfaceEcoreWl::ReplaceEGLSurface( EglInterface& egl )
150 DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
157 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
159 return eglImpl.ReplaceSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mTbmQueue ) );
162 void NativeRenderSurfaceEcoreWl::MoveResize( Dali::PositionSize positionSize )
166 void NativeRenderSurfaceEcoreWl::SetViewMode( ViewMode viewMode )
170 void NativeRenderSurfaceEcoreWl::StartRender()
174 bool NativeRenderSurfaceEcoreWl::PreRender( EglInterface&, Integration::GlAbstraction&, bool )
176 // nothing to do for pixmaps
180 void NativeRenderSurfaceEcoreWl::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface )
182 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
183 eglImpl.SwapBuffers();
185 if( mThreadSynchronization )
187 mThreadSynchronization->PostRenderStarted();
190 if( tbm_surface_queue_can_acquire( mTbmQueue, 1 ) )
192 if( tbm_surface_queue_acquire( mTbmQueue, &mConsumeSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
194 DALI_LOG_ERROR( "Failed to aquire a tbm_surface\n" );
199 tbm_surface_internal_ref( mConsumeSurface );
201 if( replacingSurface )
203 ConditionalWait::ScopedLock lock( mTbmSurfaceCondition );
204 mDrawableCompleted = true;
205 mTbmSurfaceCondition.Notify( lock );
208 // create damage for client applications which wish to know the update timing
209 if( !replacingSurface && mRenderNotification )
211 // use notification trigger
212 // Tell the event-thread to render the tbm_surface
213 mRenderNotification->Trigger();
216 if( mThreadSynchronization )
218 // wait until the event-thread completed to use the tbm_surface
219 mThreadSynchronization->PostRenderWaitForCompletion();
222 // release the consumed surface after post render was completed
226 void NativeRenderSurfaceEcoreWl::StopRender()
231 void NativeRenderSurfaceEcoreWl::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization )
233 mThreadSynchronization = &threadSynchronization;
236 RenderSurface::Type NativeRenderSurfaceEcoreWl::GetSurfaceType()
238 return RenderSurface::NATIVE_RENDER_SURFACE;
241 void NativeRenderSurfaceEcoreWl::ReleaseLock()
243 if( mThreadSynchronization )
245 mThreadSynchronization->PostRenderComplete();
249 void NativeRenderSurfaceEcoreWl::CreateNativeRenderable()
251 // check we're creating one with a valid size
252 DALI_ASSERT_ALWAYS( mPosition.width > 0 && mPosition.height > 0 && "tbm_surface size is invalid" );
254 mTbmQueue = tbm_surface_queue_create( 3, mPosition.width, mPosition.height, mTbmFormat, TBM_BO_DEFAULT );
266 void NativeRenderSurfaceEcoreWl::ReleaseDrawable()
268 if( mConsumeSurface )
270 tbm_surface_internal_unref( mConsumeSurface );
272 if( tbm_surface_internal_is_valid( mConsumeSurface ) )
274 tbm_surface_queue_release( mTbmQueue, mConsumeSurface );
276 mConsumeSurface = NULL;