Support GL Client
[platform/core/uifw/pepper-dali.git] / pepper-dali / internal / compositor-impl.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <pepper-dali/internal/compositor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <wayland-server.h>
24 #include <tizen-extension-client-protocol.h>
25 #include <Ecore_Wayland.h>
26
27 namespace Dali
28 {
29
30 namespace Pepper
31 {
32
33 namespace Internal
34 {
35
36 namespace
37 {
38
39 #if defined(DEBUG_ENABLED)
40 Integration::Log::Filter* gPepperCompositorLogging  = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_PEPPER_COMPOSITOR" );
41 #endif
42
43 static void EmbeddedCompositorGetSocket( void* data, struct tizen_embedded_compositor* embeddedCompositor, int fd )
44 {
45   int* socketFd = (int*)data;
46
47   *socketFd = fd;
48   return;
49 }
50
51 static const struct tizen_embedded_compositor_listener tizenEmbeddedCompositorListener =
52 {
53   EmbeddedCompositorGetSocket
54 };
55
56 } // unnamed namespace
57
58 CompositorPtr Compositor::New( Application application, const std::string& name )
59 {
60   CompositorPtr impl = new Compositor();
61
62   // Second-phase init of the implementation
63   impl->Initialize( application, name );
64
65   return impl;
66 }
67
68 Compositor::Compositor()
69 : mCompositor( NULL ),
70   mDisplay( NULL ),
71   mEventLoop( NULL ),
72   mFdHandler( NULL ),
73   mTbmServer( NULL ),
74   mShell( NULL ),
75   mInput( NULL ),
76   mOutput( NULL ),
77   mSocketName()
78 {
79 }
80
81 Compositor::~Compositor()
82 {
83   if( mTbmServer )
84   {
85     wayland_tbm_server_deinit( mTbmServer );
86   }
87
88   if( mCompositor )
89   {
90     pepper_compositor_destroy( mCompositor );
91   }
92
93   if( mFdHandler )
94   {
95     ecore_main_fd_handler_del( mFdHandler );
96   }
97 }
98
99 void* Compositor::GetCompositorHandle()
100 {
101   return static_cast< void* >( mCompositor );
102 }
103
104 void Compositor::Initialize( Application application, const std::string& name )
105 {
106   // Get socket fd from server
107   int socketFd = GetSocketFdFromServer();
108   if( socketFd == -1 )
109   {
110     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: socket fd is invalid.\n" );
111     return;
112   }
113
114   // create compositor
115   mCompositor = pepper_compositor_create_fd( name.c_str(), socketFd );
116   if( !mCompositor )
117   {
118     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: pepper_compositor_create_fd is failed. [%d]\n", socketFd );
119     return;
120   }
121
122   mDisplay = pepper_compositor_get_display( mCompositor );
123
124   // create shell
125   mShell = Pepper::Shell::New( Pepper::Compositor( this ) );
126   if( !mShell )
127   {
128     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: Fail to create shell.\n" );
129     pepper_compositor_destroy( mCompositor );
130     mCompositor = NULL;
131     return;
132   }
133
134   mTbmServer = wayland_tbm_server_init( mDisplay, NULL, -1, 0 );
135   if( !mTbmServer )
136   {
137     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: wayland_tbm_server_init is failed.\n" );
138     pepper_compositor_destroy( mCompositor );
139     mCompositor = NULL;
140     return;
141   }
142
143   // create input
144   mInput = Pepper::Input::New( Pepper::Compositor( this ) );
145   if( !mInput )
146   {
147     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: Fail to create input.\n" );
148     wayland_tbm_server_deinit( mTbmServer );
149     mTbmServer = NULL;
150     pepper_compositor_destroy( mCompositor );
151     mCompositor = NULL;
152     return;
153   }
154
155   mSocketName = pepper_compositor_get_socket_name( mCompositor );
156
157   mEventLoop = wl_display_get_event_loop( mDisplay );
158
159   int loopFd = wl_event_loop_get_fd( mEventLoop );
160
161   mFdHandler = ecore_main_fd_handler_add( loopFd, (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR), Compositor::FdReadCallback, this, NULL, NULL );
162
163   ecore_main_fd_handler_prepare_callback_set( mFdHandler, Compositor::FdPrepareCallback, this );
164
165   // create output
166   mOutput = Pepper::Output::New( Pepper::Compositor( this ), application, mInput );
167   if( !mOutput )
168   {
169     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: Fail to create output.\n" );
170
171     ecore_main_fd_handler_del( mFdHandler );
172     mFdHandler = NULL;
173     wayland_tbm_server_deinit( mTbmServer );
174     mTbmServer = NULL;
175     pepper_compositor_destroy( mCompositor );
176     mCompositor = NULL;
177     return;
178   }
179
180   mOutput.ObjectViewAddedSignal().Connect( this, &Compositor::OnObjectViewAdded );
181   mOutput.ObjectViewDeletedSignal().Connect( this, &Compositor::OnObjectViewDeleted );
182
183   DALI_LOG_INFO( gPepperCompositorLogging, Debug::Verbose, "Compositor::Initialize: success. socket name = %s\n", mSocketName.c_str() );
184
185   // TODO: temp
186   setenv("WAYLAND_DISPLAY", mSocketName.c_str(), 1);
187 }
188
189 int Compositor::GetSocketFdFromServer()
190 {
191   Eina_Inlist* list;
192   Eina_Inlist* tmp;
193   Ecore_Wl_Global* global;
194   struct tizen_embedded_compositor* embeddedCompositor = NULL;
195   int fd = -1;
196
197   list = ecore_wl_globals_get();
198   if( !list )
199   {
200     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::GetSocketFdFromServer: ecore_wl_globals_get returns NULL.\n" );
201     return -1;
202   }
203
204   EINA_INLIST_FOREACH_SAFE( list, tmp, global )
205   {
206     if( !strcmp( global->interface, "tizen_embedded_compositor" ) )
207     {
208       embeddedCompositor = static_cast< struct tizen_embedded_compositor* >( wl_registry_bind( ecore_wl_registry_get(), global->id, &tizen_embedded_compositor_interface, 1 ) );
209
210       tizen_embedded_compositor_add_listener( embeddedCompositor, &tizenEmbeddedCompositorListener, &fd );
211       break;
212     }
213   }
214
215   if( !embeddedCompositor )
216   {
217     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::GetSocketFdFromServer: tizen_embedded_compositor is not supported.\n" );
218     return -1;
219   }
220
221   tizen_embedded_compositor_get_socket( embeddedCompositor );
222   ecore_wl_sync();
223
224   tizen_embedded_compositor_destroy( embeddedCompositor );
225
226   return fd;
227 }
228
229 Pepper::Compositor::CompositorSignalType& Compositor::ObjectViewAddedSignal()
230 {
231   return mObjectViewAddedSignal;
232 }
233
234 Pepper::Compositor::CompositorSignalType& Compositor::ObjectViewDeletedSignal()
235 {
236   return mObjectViewDeletedSignal;
237 }
238
239 void Compositor::OnObjectViewAdded( Pepper::Output output, Pepper::ObjectView objectView )
240 {
241   Pepper::Compositor handle( this );
242   mObjectViewAddedSignal.Emit( handle, objectView );
243
244   DALI_LOG_INFO( gPepperCompositorLogging, Debug::Verbose, "Compositor::ObjectViewAddedSignal: ObjectView is added!\n" );
245 }
246
247 void Compositor::OnObjectViewDeleted( Pepper::Output output, Pepper::ObjectView objectView )
248 {
249   Pepper::Compositor handle( this );
250   mObjectViewDeletedSignal.Emit( handle, objectView );
251
252   DALI_LOG_INFO( gPepperCompositorLogging, Debug::Verbose, "Compositor::ObjectViewDeletedSignal: ObjectView is deleted!\n" );
253 }
254
255 Eina_Bool Compositor::FdReadCallback( void* data, Ecore_Fd_Handler* handler )
256 {
257   Compositor* compositor = static_cast< Compositor* >( data );
258
259   wl_event_loop_dispatch( compositor->mEventLoop, 0 );
260
261   return ECORE_CALLBACK_RENEW;
262 }
263
264 void Compositor::FdPrepareCallback( void* data, Ecore_Fd_Handler* handler )
265 {
266   Compositor* compositor = static_cast< Compositor* >( data );
267
268   wl_display_flush_clients( compositor->mDisplay );
269 }
270
271 } // namespace Internal
272
273 } // namespace Pepper
274
275 } // namespace Dali