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