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>
26 #include <Ecore_Wl2.h>
28 #include <Ecore_Wayland.h>
31 #include <tbm_bufmgr.h>
32 #include <tbm_surface_internal.h>
35 #include <dali/internal/system/common/trigger-event.h>
36 #include <dali/internal/graphics/gles/egl-implementation.h>
37 #include <dali/internal/graphics/gles/egl-graphics.h>
38 #include <dali/internal/window-system/common/display-connection.h>
39 #include <dali/internal/window-system/common/window-system.h>
40 #include <dali/integration-api/thread-synchronization-interface.h>
48 #if defined(DEBUG_ENABLED)
49 Debug::Filter* gNativeSurfaceLogFilter = Debug::Filter::New(Debug::Verbose, false, "LOG_NATIVE_RENDER_SURFACE");
52 } // unnamed namespace
54 NativeRenderSurfaceEcoreWl::NativeRenderSurfaceEcoreWl( Dali::PositionSize positionSize, bool isTransparent )
55 : mPosition( positionSize ),
56 mRenderNotification( NULL ),
57 mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ),
58 mTbmFormat( isTransparent ? TBM_FORMAT_ARGB8888 : TBM_FORMAT_RGB888 ),
60 mDrawableCompleted( false ),
62 mConsumeSurface( NULL ),
63 mThreadSynchronization( NULL )
65 Dali::Internal::Adaptor::WindowSystem::Initialize();
67 CreateNativeRenderable();
68 setenv( "EGL_PLATFORM", "tbm", 1 );
71 NativeRenderSurfaceEcoreWl::~NativeRenderSurfaceEcoreWl()
73 // release the surface if we own one
80 tbm_surface_queue_destroy( mTbmQueue );
83 DALI_LOG_INFO( gNativeSurfaceLogFilter, Debug::General, "Own tbm surface queue destroy\n" );
86 Dali::Internal::Adaptor::WindowSystem::Shutdown();
89 Any NativeRenderSurfaceEcoreWl::GetDrawable()
91 return mConsumeSurface;
94 void NativeRenderSurfaceEcoreWl::SetRenderNotification( TriggerEventInterface* renderNotification )
96 mRenderNotification = renderNotification;
99 void NativeRenderSurfaceEcoreWl::WaitUntilSurfaceReplaced()
101 ConditionalWait::ScopedLock lock( mTbmSurfaceCondition );
102 while( !mDrawableCompleted )
104 mTbmSurfaceCondition.Wait( lock );
107 mDrawableCompleted = false;
110 PositionSize NativeRenderSurfaceEcoreWl::GetPositionSize() const
115 void NativeRenderSurfaceEcoreWl::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical )
120 // 1 inch = 25.4 millimeters
121 #ifdef ECORE_WAYLAND2
122 // TODO: Application should set dpi value in wayland2
126 xres = ecore_wl_dpi_get();
127 yres = ecore_wl_dpi_get();
130 dpiHorizontal = int( xres + 0.5f ); // rounding
131 dpiVertical = int( yres + 0.5f );
134 void NativeRenderSurfaceEcoreWl::InitializeGraphics( Internal::Adaptor::GraphicsInterface& graphics, DisplayConnection& displayConnection )
136 DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
137 unsetenv( "EGL_PLATFORM" );
139 mGraphics = &graphics;
141 auto eglGraphics = static_cast<Internal::Adaptor::EglGraphics *>(mGraphics);
143 EglInterface* mEGL = eglGraphics->Create();
145 // Initialize EGL & OpenGL
146 displayConnection.Initialize();
148 Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>(*mEGL);
149 eglImpl.ChooseConfig(true, mColorDepth);
151 // Create the OpenGL context
152 mEGL->CreateContext();
154 // Create the OpenGL surface
158 mEGL->MakeContextCurrent();
161 void NativeRenderSurfaceEcoreWl::CreateSurface()
163 DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
165 auto eglGraphics = static_cast<Internal::Adaptor::EglGraphics *>(mGraphics);
166 Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
168 eglImpl.CreateSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mTbmQueue ), mColorDepth );
171 void NativeRenderSurfaceEcoreWl::DestroySurface()
173 DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
175 auto eglGraphics = static_cast<Internal::Adaptor::EglGraphics *>(mGraphics);
176 Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
178 eglImpl.DestroySurface();
181 bool NativeRenderSurfaceEcoreWl::ReplaceGraphicsSurface()
183 DALI_LOG_TRACE_METHOD( gNativeSurfaceLogFilter );
190 auto eglGraphics = static_cast<Internal::Adaptor::EglGraphics *>(mGraphics);
191 Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
193 return eglImpl.ReplaceSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( mTbmQueue ) );
196 void NativeRenderSurfaceEcoreWl::MoveResize( Dali::PositionSize positionSize )
200 void NativeRenderSurfaceEcoreWl::SetViewMode( ViewMode viewMode )
204 void NativeRenderSurfaceEcoreWl::StartRender()
208 bool NativeRenderSurfaceEcoreWl::PreRender( bool )
210 // nothing to do for pixmaps
214 void NativeRenderSurfaceEcoreWl::PostRender( bool renderToFbo, bool replacingSurface, bool resizingSurface )
216 auto eglGraphics = static_cast<Internal::Adaptor::EglGraphics *>(mGraphics);
217 Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation();
219 eglImpl.SwapBuffers();
221 if( mThreadSynchronization )
223 mThreadSynchronization->PostRenderStarted();
226 if( tbm_surface_queue_can_acquire( mTbmQueue, 1 ) )
228 if( tbm_surface_queue_acquire( mTbmQueue, &mConsumeSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
230 DALI_LOG_ERROR( "Failed to acquire a tbm_surface\n" );
235 tbm_surface_internal_ref( mConsumeSurface );
237 if( replacingSurface )
239 ConditionalWait::ScopedLock lock( mTbmSurfaceCondition );
240 mDrawableCompleted = true;
241 mTbmSurfaceCondition.Notify( lock );
244 // create damage for client applications which wish to know the update timing
245 if( !replacingSurface && mRenderNotification )
247 // use notification trigger
248 // Tell the event-thread to render the tbm_surface
249 mRenderNotification->Trigger();
252 if( mThreadSynchronization )
254 // wait until the event-thread completed to use the tbm_surface
255 mThreadSynchronization->PostRenderWaitForCompletion();
258 // release the consumed surface after post render was completed
262 void NativeRenderSurfaceEcoreWl::StopRender()
267 void NativeRenderSurfaceEcoreWl::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization )
269 mThreadSynchronization = &threadSynchronization;
272 RenderSurface::Type NativeRenderSurfaceEcoreWl::GetSurfaceType()
274 return RenderSurface::NATIVE_RENDER_SURFACE;
277 void NativeRenderSurfaceEcoreWl::ReleaseLock()
279 if( mThreadSynchronization )
281 mThreadSynchronization->PostRenderComplete();
285 void NativeRenderSurfaceEcoreWl::CreateNativeRenderable()
287 // check we're creating one with a valid size
288 DALI_ASSERT_ALWAYS( mPosition.width > 0 && mPosition.height > 0 && "tbm_surface size is invalid" );
290 mTbmQueue = tbm_surface_queue_create( 3, mPosition.width, mPosition.height, mTbmFormat, TBM_BO_DEFAULT );
302 void NativeRenderSurfaceEcoreWl::ReleaseDrawable()
304 if( mConsumeSurface )
306 tbm_surface_internal_unref( mConsumeSurface );
308 if( tbm_surface_internal_is_valid( mConsumeSurface ) )
310 tbm_surface_queue_release( mTbmQueue, mConsumeSurface );
312 mConsumeSurface = NULL;