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