Merge "Fix build errors with GCC4.8." into tizen
[platform/core/uifw/dali-adaptor.git] / adaptors / x11 / pixmap-render-surface-x.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 "pixmap-render-surface.h"
20
21 // EXTERNAL INCLUDES
22 #include <X11/Xatom.h>
23 #include <X11/Xlib.h>
24 #include <X11/Xutil.h>
25
26 #include <X11/extensions/Xfixes.h> // for damage notify
27 #include <X11/extensions/Xdamage.h> // for damage notify
28
29 #include <dali/integration-api/gl-abstraction.h>
30 #include <dali/integration-api/debug.h>
31
32 // INTERNAL INCLUDES
33 #include <ecore-x-types.h>
34 #include <trigger-event.h>
35
36 namespace Dali
37 {
38
39 namespace Internal
40 {
41
42 namespace Adaptor
43 {
44
45 #if defined(DEBUG_ENABLED)
46 extern Debug::Filter* gRenderSurfaceLogFilter;
47 #endif
48
49 namespace ECore
50 {
51
52 PixmapRenderSurface::PixmapRenderSurface( Dali::PositionSize positionSize,
53                               Any surface,
54                               Any display,
55                               const std::string& name,
56                               bool isTransparent)
57 : RenderSurface( Dali::RenderSurface::PIXMAP, positionSize, surface, display, name, isTransparent )
58 {
59   Init( surface );
60 }
61
62 PixmapRenderSurface::~PixmapRenderSurface()
63 {
64   // release the surface if we own one
65   if( mOwnSurface )
66   {
67     // if we did create the pixmap, delete the pixmap
68     DALI_LOG_INFO( gRenderSurfaceLogFilter, Debug::General, "Own pixmap (%x) freed\n", mX11Pixmap );
69     ecore_x_pixmap_free( mX11Pixmap );
70   }
71 }
72
73 Ecore_X_Drawable PixmapRenderSurface::GetDrawable()
74 {
75   return (Ecore_X_Drawable)mX11Pixmap;
76 }
77
78 Dali::RenderSurface::SurfaceType PixmapRenderSurface::GetType()
79 {
80   return Dali::RenderSurface::PIXMAP;
81 }
82
83 Any PixmapRenderSurface::GetSurface()
84 {
85   return Any( mX11Pixmap );
86 }
87
88 void PixmapRenderSurface::InitializeEgl( EglInterface& eglIf )
89 {
90   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
91
92   EglImplementation& eglImpl = static_cast<EglImplementation&>( eglIf );
93   eglImpl.InitializeGles( reinterpret_cast< EGLNativeDisplayType >( mMainDisplay ) );
94
95   eglImpl.ChooseConfig(false, mColorDepth);
96 }
97
98 void PixmapRenderSurface::CreateEglSurface( EglInterface& eglIf )
99 {
100   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
101
102   EglImplementation& eglImpl = static_cast<EglImplementation&>( eglIf );
103
104   // create the EGL surface
105   // need to cast to X handle as in 64bit system ECore handle is 32 bit whereas EGLnative and XWindow are 64 bit
106   XPixmap pixmap = static_cast< XPixmap>( mX11Pixmap );
107   eglImpl.CreateSurfacePixmap( (EGLNativePixmapType)pixmap, mColorDepth ); // reinterpret_cast does not compile
108 }
109
110 void PixmapRenderSurface::DestroyEglSurface( EglInterface& eglIf )
111 {
112   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
113
114   EglImplementation& eglImpl = static_cast<EglImplementation&>( eglIf );
115   eglImpl.DestroySurface();
116 }
117
118 bool PixmapRenderSurface::ReplaceEGLSurface( EglInterface& eglIf )
119 {
120   DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
121
122   EglImplementation& eglImpl = static_cast<EglImplementation&>( eglIf );
123   eglImpl.InitializeGles( reinterpret_cast< EGLNativeDisplayType >( mMainDisplay ) );
124
125   // a new surface for the new pixmap
126   // need to cast to X handle as in 64bit system ECore handle is 32 bit whereas EGLnative and XWindow are 64 bit
127   XPixmap pixmap = static_cast< XPixmap>( mX11Pixmap );
128   return eglImpl.ReplaceSurfacePixmap( (EGLNativePixmapType)pixmap, // reinterpret_cast does not compile
129                                        reinterpret_cast< EGLNativeDisplayType >( mMainDisplay ) );
130 }
131
132 bool PixmapRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
133 {
134   // nothing to do for pixmaps
135   return true;
136 }
137
138 void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode )
139 {
140   // flush gl instruction queue
141   glAbstraction.Flush();
142
143   // create damage for client applications which wish to know the update timing
144   if( mRenderNotification )
145   {
146     // use notification trigger
147     // Tell the event-thread to render the pixmap
148     mRenderNotification->Trigger();
149   }
150   else
151   {
152     // as a fallback, send damage event. This is needed until livebox is fixed to
153     // stop using damage events for render
154     Ecore_X_Drawable drawable = GetDrawable();
155
156     if( drawable )
157     {
158       XRectangle rect;
159       XserverRegion region;
160
161       rect.x = 0;
162       rect.y = 0;
163       rect.width = mPosition.width;
164       rect.height = mPosition.height;
165
166       // make a fixes region as updated area
167       region = XFixesCreateRegion( mMainDisplay, &rect, 1 );
168       // add damage event to updated drawable
169       XDamageAdd( mMainDisplay, (Drawable)drawable, region );
170       XFixesDestroyRegion( mMainDisplay, region );
171
172       XFlush( mMainDisplay );
173     }
174   }
175
176   // Do render synchronisation
177   DoRenderSync( timeDelta, syncMode );
178 }
179
180 void PixmapRenderSurface::CreateXRenderable()
181 {
182   // check we're creating one with a valid size
183   DALI_ASSERT_ALWAYS( mPosition.width > 0 && mPosition.height > 0 && "Pixmap size is invalid" );
184
185   // create the pixmap
186   mX11Pixmap = ecore_x_pixmap_new(0, mPosition.width, mPosition.height, mColorDepth);
187
188   // clear the pixmap
189   unsigned int foreground;
190   Ecore_X_GC gc;
191   foreground = 0;
192   gc = ecore_x_gc_new( mX11Pixmap,
193                        ECORE_X_GC_VALUE_MASK_FOREGROUND,
194                        &foreground );
195   ecore_x_drawable_rectangle_fill( mX11Pixmap, gc, 0, 0, mPosition.width, mPosition.height );
196
197   DALI_ASSERT_ALWAYS( mX11Pixmap && "Failed to create X pixmap" );
198
199   // we SHOULD guarantee the xpixmap/x11 window was created in x server.
200   ecore_x_sync();
201
202   ecore_x_gc_free(gc);
203 }
204
205 void PixmapRenderSurface::UseExistingRenderable( unsigned int surfaceId )
206 {
207   mX11Pixmap = static_cast< Ecore_X_Pixmap >( surfaceId );
208 }
209
210 void PixmapRenderSurface::RenderSync()
211 {
212   {
213     boost::unique_lock< boost::mutex > lock( mSyncMutex );
214     mSyncReceived = true;
215   }
216
217   // wake render thread if it was waiting for the notify
218   mSyncNotify.notify_all();
219 }
220
221 } // namespace ECore
222
223 } // namespace Adaptor
224
225 } // namespace Internal
226
227 } // namespace Dali