da42e934143f825237d5e27fd50604436c35e519
[platform/core/uifw/dali-adaptor.git] / adaptors / ecore / wayland / window-render-surface-ecore-wl.cpp
1 /*
2  * Copyright (c) 2014 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 "window-render-surface.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/gl-abstraction.h>
23 #include <dali/integration-api/debug.h>
24
25 // INTERNAL INCLUDES
26 #include <wl-types.h>
27 #include <trigger-event.h>
28 #include <gl/egl-implementation.h>
29 #include <base/display-connection.h>
30
31 namespace Dali
32 {
33
34 #if defined(DEBUG_ENABLED)
35 extern Debug::Filter* gRenderSurfaceLogFilter;
36 #endif
37
38 namespace ECore
39 {
40
41 namespace
42 {
43
44 const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved
45
46 } // unnamed namespace
47
48 WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize,
49                                           Any surface,
50                                           const std::string& name,
51                                           bool isTransparent)
52 : EcoreWlRenderSurface( positionSize, surface, name, isTransparent ),
53   mEglWindow( NULL ),
54   mNeedToApproveDeiconify( false )
55 {
56   DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" );
57   Init( surface );
58 }
59
60 WindowRenderSurface::~WindowRenderSurface()
61 {
62   if( mEglWindow != NULL )
63   {
64     wl_egl_window_destroy(mEglWindow);
65     mEglWindow = NULL;
66   }
67
68   if( mOwnSurface )
69   {
70     ecore_wl_window_free( mWlWindow );
71   }
72 }
73
74 Ecore_Wl_Window* WindowRenderSurface::GetDrawable()
75 {
76   // already an e-core type
77   return mWlWindow;
78 }
79
80 Any WindowRenderSurface::GetSurface()
81 {
82   // already an e-core type
83   return Any( mWlWindow );
84 }
85
86 Ecore_Wl_Window* WindowRenderSurface::GetWlWindow()
87 {
88   return mWlWindow;
89 }
90
91 void WindowRenderSurface::RequestToApproveDeiconify()
92 {
93   mNeedToApproveDeiconify = true;
94 }
95
96 void WindowRenderSurface::InitializeEgl( EglInterface& eglIf )
97 {
98   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
99
100   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
101
102   eglImpl.ChooseConfig(true, mColorDepth);
103 }
104
105 void WindowRenderSurface::CreateEglSurface( EglInterface& eglIf )
106 {
107   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
108
109   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
110
111   // Temporary code for opaque window. We have to modify it after wayland team finish the work.
112   if( mColorDepth == COLOR_DEPTH_32 )
113   {
114     ecore_wl_window_alpha_set( mWlWindow, true );
115   }
116   else
117   {
118     ecore_wl_window_alpha_set( mWlWindow, false );
119   }
120
121   // create the EGL surface
122   ecore_wl_window_surface_create(mWlWindow);
123   mEglWindow = wl_egl_window_create(ecore_wl_window_surface_get(mWlWindow), mPosition.width, mPosition.height);
124   eglImpl.CreateSurfaceWindow( (EGLNativeWindowType)mEglWindow, mColorDepth ); // reinterpret_cast does not compile
125 }
126
127 void WindowRenderSurface::DestroyEglSurface( EglInterface& eglIf )
128 {
129   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
130
131   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( eglIf );
132   eglImpl.DestroySurface();
133
134   if( mEglWindow != NULL )
135   {
136     wl_egl_window_destroy(mEglWindow);
137     mEglWindow = NULL;
138   }
139 }
140
141 bool WindowRenderSurface::ReplaceEGLSurface( EglInterface& egl )
142 {
143   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
144
145   if( mEglWindow != NULL )
146   {
147     wl_egl_window_destroy(mEglWindow);
148     mEglWindow = NULL;
149   }
150
151   // Temporary code for opaque window. We have to modify it after wayland team finish the work.
152   if( mColorDepth == COLOR_DEPTH_32 )
153   {
154     ecore_wl_window_alpha_set( mWlWindow, true );
155   }
156   else
157   {
158     ecore_wl_window_alpha_set( mWlWindow, false );
159   }
160
161   mEglWindow = wl_egl_window_create(ecore_wl_window_surface_get(mWlWindow), mPosition.width, mPosition.height);
162
163   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
164   return eglImpl.ReplaceSurfaceWindow( (EGLNativeWindowType)mEglWindow ); // reinterpret_cast does not compile
165 }
166
167 void WindowRenderSurface::MoveResize( Dali::PositionSize positionSize )
168 {
169   bool needToMove = false;
170   bool needToResize = false;
171
172   // check moving
173   if( (fabs(positionSize.x - mPosition.x) > MINIMUM_DIMENSION_CHANGE) ||
174       (fabs(positionSize.y - mPosition.y) > MINIMUM_DIMENSION_CHANGE) )
175   {
176     needToMove = true;
177   }
178
179   // check resizing
180   if( (fabs(positionSize.width - mPosition.width) > MINIMUM_DIMENSION_CHANGE) ||
181       (fabs(positionSize.height - mPosition.height) > MINIMUM_DIMENSION_CHANGE) )
182   {
183     needToResize = true;
184   }
185
186   if(needToMove)
187   {
188     ecore_wl_window_move(mWlWindow, positionSize.x, positionSize.y);
189     mPosition = positionSize;
190   }
191   if (needToResize)
192   {
193     ecore_wl_window_resize(mWlWindow, positionSize.width, positionSize.height, 0);
194     mPosition = positionSize;
195   }
196
197 }
198
199 void WindowRenderSurface::Map()
200 {
201   ecore_wl_window_show(mWlWindow);
202 }
203
204 void WindowRenderSurface::StartRender()
205 {
206 }
207
208 bool WindowRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
209 {
210   // nothing to do for windows
211   return true;
212 }
213
214 void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface )
215 {
216   Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( egl );
217   eglImpl.SwapBuffers();
218
219   if( mRenderNotification )
220   {
221     mRenderNotification->Trigger();
222   }
223
224   // When the window is deiconified, it approves the deiconify operation to window manager after rendering
225   if(mNeedToApproveDeiconify)
226   {
227     // SwapBuffer is desychronized. So make sure to sychronize when window is deiconified.
228     glAbstraction.Finish();
229
230     //FIXME
231
232     mNeedToApproveDeiconify = false;
233   }
234 }
235
236 void WindowRenderSurface::StopRender()
237 {
238 }
239
240 void WindowRenderSurface::SetViewMode( ViewMode viewMode )
241 {
242   //FIXME
243 }
244
245 void WindowRenderSurface::CreateWlRenderable()
246 {
247    // if width or height are zero, go full screen.
248   if ( (mPosition.width == 0) || (mPosition.height == 0) )
249   {
250     // Default window size == screen size
251     mPosition.x = 0;
252     mPosition.y = 0;
253
254     ecore_wl_screen_size_get( &mPosition.width, &mPosition.height );
255   }
256
257   mWlWindow = ecore_wl_window_new( 0, mPosition.x, mPosition.y, mPosition.width, mPosition.height, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW );
258
259   if ( mWlWindow == 0 )
260   {
261       DALI_ASSERT_ALWAYS(0 && "Failed to create X window");
262   }
263 }
264
265 void WindowRenderSurface::UseExistingRenderable( unsigned int surfaceId )
266 {
267   mWlWindow = AnyCast< Ecore_Wl_Window* >( surfaceId );
268 }
269
270 void WindowRenderSurface::SetThreadSynchronization( ThreadSynchronizationInterface& /* threadSynchronization */ )
271 {
272   // Nothing to do.
273 }
274
275 void WindowRenderSurface::ReleaseLock()
276 {
277   // Nothing to do.
278 }
279
280 } // namespace ECore
281
282 } // namespace Dali