a458cbeb3f9cf62d4b023c2a9e83718ddb620c6d
[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 const std::string& Compositor::GetName() const
100 {
101   return mSocketName;
102 }
103
104 void* Compositor::GetCompositorHandle()
105 {
106   return static_cast< void* >( mCompositor );
107 }
108
109 void Compositor::Initialize( Application application, const std::string& name )
110 {
111   // Get socket fd from server
112   int socketFd = GetSocketFdFromServer();
113   if( socketFd == -1 )
114   {
115     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: socket fd is invalid.\n" );
116     return;
117   }
118
119   // create compositor
120   mCompositor = pepper_compositor_create_fd( name.c_str(), socketFd );
121   if( !mCompositor )
122   {
123     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: pepper_compositor_create_fd is failed. [%d]\n", socketFd );
124     return;
125   }
126
127   mDisplay = pepper_compositor_get_display( mCompositor );
128
129   // create shell
130   mShell = Pepper::Shell::New( Pepper::Compositor( this ) );
131   if( !mShell )
132   {
133     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: Fail to create shell.\n" );
134     pepper_compositor_destroy( mCompositor );
135     mCompositor = NULL;
136     return;
137   }
138
139   mTbmServer = wayland_tbm_server_init( mDisplay, NULL, -1, 0 );
140   if( !mTbmServer )
141   {
142     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: wayland_tbm_server_init is failed.\n" );
143     pepper_compositor_destroy( mCompositor );
144     mCompositor = NULL;
145     return;
146   }
147
148   // create input
149   mInput = Pepper::Input::New( Pepper::Compositor( this ) );
150   if( !mInput )
151   {
152     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: Fail to create input.\n" );
153     wayland_tbm_server_deinit( mTbmServer );
154     mTbmServer = NULL;
155     pepper_compositor_destroy( mCompositor );
156     mCompositor = NULL;
157     return;
158   }
159
160   mSocketName = pepper_compositor_get_socket_name( mCompositor );
161
162   mEventLoop = wl_display_get_event_loop( mDisplay );
163
164   int loopFd = wl_event_loop_get_fd( mEventLoop );
165
166   mFdHandler = ecore_main_fd_handler_add( loopFd, (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR), Compositor::FdReadCallback, this, NULL, NULL );
167
168   ecore_main_fd_handler_prepare_callback_set( mFdHandler, Compositor::FdPrepareCallback, this );
169
170   // create output
171   mOutput = Pepper::Output::New( Pepper::Compositor( this ), application, mInput );
172   if( !mOutput )
173   {
174     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::Initialize: Fail to create output.\n" );
175
176     ecore_main_fd_handler_del( mFdHandler );
177     mFdHandler = NULL;
178     wayland_tbm_server_deinit( mTbmServer );
179     mTbmServer = NULL;
180     pepper_compositor_destroy( mCompositor );
181     mCompositor = NULL;
182     return;
183   }
184
185   mOutput.ObjectViewAddedSignal().Connect( this, &Compositor::OnObjectViewAdded );
186   mOutput.ObjectViewDeletedSignal().Connect( this, &Compositor::OnObjectViewDeleted );
187
188   DALI_LOG_INFO( gPepperCompositorLogging, Debug::Verbose, "Compositor::Initialize: success. socket name = %s\n", mSocketName.c_str() );
189 }
190
191 int Compositor::GetSocketFdFromServer()
192 {
193   Eina_Inlist* list;
194   Eina_Inlist* tmp;
195   Ecore_Wl_Global* global;
196   struct tizen_embedded_compositor* embeddedCompositor = NULL;
197   int fd = -1;
198
199   list = ecore_wl_globals_get();
200   if( !list )
201   {
202     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::GetSocketFdFromServer: ecore_wl_globals_get returns NULL.\n" );
203     return -1;
204   }
205
206   EINA_INLIST_FOREACH_SAFE( list, tmp, global )
207   {
208     if( !strcmp( global->interface, "tizen_embedded_compositor" ) )
209     {
210       embeddedCompositor = static_cast< struct tizen_embedded_compositor* >( wl_registry_bind( ecore_wl_registry_get(), global->id, &tizen_embedded_compositor_interface, 1 ) );
211
212       tizen_embedded_compositor_add_listener( embeddedCompositor, &tizenEmbeddedCompositorListener, &fd );
213       break;
214     }
215   }
216
217   if( !embeddedCompositor )
218   {
219     DALI_LOG_INFO( gPepperCompositorLogging, Debug::General, "Compositor::GetSocketFdFromServer: tizen_embedded_compositor is not supported.\n" );
220     return -1;
221   }
222
223   tizen_embedded_compositor_get_socket( embeddedCompositor );
224   ecore_wl_sync();
225
226   tizen_embedded_compositor_destroy( embeddedCompositor );
227
228   return fd;
229 }
230
231 Pepper::Compositor::CompositorSignalType& Compositor::ObjectViewAddedSignal()
232 {
233   return mObjectViewAddedSignal;
234 }
235
236 Pepper::Compositor::CompositorSignalType& Compositor::ObjectViewDeletedSignal()
237 {
238   return mObjectViewDeletedSignal;
239 }
240
241 void Compositor::OnObjectViewAdded( Pepper::Output output, Pepper::ObjectView objectView )
242 {
243   Pepper::Compositor handle( this );
244   mObjectViewAddedSignal.Emit( handle, objectView );
245
246   DALI_LOG_INFO( gPepperCompositorLogging, Debug::Verbose, "Compositor::ObjectViewAddedSignal: ObjectView is added!\n" );
247 }
248
249 void Compositor::OnObjectViewDeleted( Pepper::Output output, Pepper::ObjectView objectView )
250 {
251   Pepper::Compositor handle( this );
252   mObjectViewDeletedSignal.Emit( handle, objectView );
253
254   DALI_LOG_INFO( gPepperCompositorLogging, Debug::Verbose, "Compositor::ObjectViewDeletedSignal: ObjectView is deleted!\n" );
255 }
256
257 Eina_Bool Compositor::FdReadCallback( void* data, Ecore_Fd_Handler* handler )
258 {
259   Compositor* compositor = static_cast< Compositor* >( data );
260
261   wl_event_loop_dispatch( compositor->mEventLoop, 0 );
262
263   return ECORE_CALLBACK_RENEW;
264 }
265
266 void Compositor::FdPrepareCallback( void* data, Ecore_Fd_Handler* handler )
267 {
268   Compositor* compositor = static_cast< Compositor* >( data );
269
270   wl_display_flush_clients( compositor->mDisplay );
271 }
272
273 } // namespace Internal
274
275 } // namespace Pepper
276
277 } // namespace Dali