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