2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "pixmap-render-surface.h"
22 #include <X11/Xatom.h>
24 #include <X11/Xutil.h>
26 #include <X11/extensions/Xfixes.h> // for damage notify
27 #include <X11/extensions/Xdamage.h> // for damage notify
29 #include <dali/integration-api/gl-abstraction.h>
30 #include <dali/integration-api/debug.h>
33 #include <ecore-x-types.h>
34 #include <trigger-event.h>
45 #if defined(DEBUG_ENABLED)
46 extern Debug::Filter* gRenderSurfaceLogFilter;
52 PixmapRenderSurface::PixmapRenderSurface( Dali::PositionSize positionSize,
55 const std::string& name,
57 : RenderSurface( Dali::RenderSurface::PIXMAP, positionSize, surface, display, name, isTransparent )
62 PixmapRenderSurface::~PixmapRenderSurface()
64 // release the surface if we own one
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 );
73 Ecore_X_Drawable PixmapRenderSurface::GetDrawable()
75 return (Ecore_X_Drawable)mX11Pixmap;
78 Dali::RenderSurface::SurfaceType PixmapRenderSurface::GetType()
80 return Dali::RenderSurface::PIXMAP;
83 Any PixmapRenderSurface::GetSurface()
85 return Any( mX11Pixmap );
88 void PixmapRenderSurface::InitializeEgl( EglInterface& eglIf )
90 DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
92 EglImplementation& eglImpl = static_cast<EglImplementation&>( eglIf );
93 eglImpl.InitializeGles( reinterpret_cast< EGLNativeDisplayType >( mMainDisplay ) );
95 eglImpl.ChooseConfig(false, mColorDepth);
98 void PixmapRenderSurface::CreateEglSurface( EglInterface& eglIf )
100 DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
102 EglImplementation& eglImpl = static_cast<EglImplementation&>( eglIf );
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
110 void PixmapRenderSurface::DestroyEglSurface( EglInterface& eglIf )
112 DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
114 EglImplementation& eglImpl = static_cast<EglImplementation&>( eglIf );
115 eglImpl.DestroySurface();
118 bool PixmapRenderSurface::ReplaceEGLSurface( EglInterface& eglIf )
120 DALI_LOG_TRACE_METHOD( gRenderSurfaceLogFilter );
122 EglImplementation& eglImpl = static_cast<EglImplementation&>( eglIf );
123 eglImpl.InitializeGles( reinterpret_cast< EGLNativeDisplayType >( mMainDisplay ) );
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 ) );
132 bool PixmapRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
134 // nothing to do for pixmaps
138 void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode )
140 // flush gl instruction queue
141 glAbstraction.Flush();
143 // create damage for client applications which wish to know the update timing
144 if( mRenderNotification )
146 // use notification trigger
147 // Tell the event-thread to render the pixmap
148 mRenderNotification->Trigger();
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();
159 XserverRegion region;
163 rect.width = mPosition.width;
164 rect.height = mPosition.height;
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 );
172 XFlush( mMainDisplay );
176 // Do render synchronisation
177 DoRenderSync( timeDelta, syncMode );
180 void PixmapRenderSurface::CreateXRenderable()
182 // check we're creating one with a valid size
183 DALI_ASSERT_ALWAYS( mPosition.width > 0 && mPosition.height > 0 && "Pixmap size is invalid" );
186 mX11Pixmap = ecore_x_pixmap_new(0, mPosition.width, mPosition.height, mColorDepth);
189 unsigned int foreground;
192 gc = ecore_x_gc_new( mX11Pixmap,
193 ECORE_X_GC_VALUE_MASK_FOREGROUND,
195 ecore_x_drawable_rectangle_fill( mX11Pixmap, gc, 0, 0, mPosition.width, mPosition.height );
197 DALI_ASSERT_ALWAYS( mX11Pixmap && "Failed to create X pixmap" );
199 // we SHOULD guarantee the xpixmap/x11 window was created in x server.
205 void PixmapRenderSurface::UseExistingRenderable( unsigned int surfaceId )
207 mX11Pixmap = static_cast< Ecore_X_Pixmap >( surfaceId );
210 void PixmapRenderSurface::RenderSync()
213 boost::unique_lock< boost::mutex > lock( mSyncMutex );
214 mSyncReceived = true;
217 // wake render thread if it was waiting for the notify
218 mSyncNotify.notify_all();
223 } // namespace Adaptor
225 } // namespace Internal